From d0ce2c3e6c252dfb5edd6dd6996684f48fe68d6c Mon Sep 17 00:00:00 2001 From: "bernard.xiong" Date: Fri, 6 Nov 2009 07:44:39 +0000 Subject: [PATCH] update hdc image support git-svn-id: https://rt-thread.googlecode.com/svn/trunk@155 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- rtgui/common/image_hdc.c | 231 ++++++++++++++++++++------------------- 1 file changed, 121 insertions(+), 110 deletions(-) diff --git a/rtgui/common/image_hdc.c b/rtgui/common/image_hdc.c index f5dc561dd8..b38a276c7e 100644 --- a/rtgui/common/image_hdc.c +++ b/rtgui/common/image_hdc.c @@ -1,6 +1,5 @@ -#include "libpng/png.h" #include -#include +#include #include #define HDC_MAGIC_LEN 4 @@ -10,11 +9,13 @@ struct rtgui_image_hdc rt_bool_t is_loaded; struct rtgui_filerw* filerw; + struct rtgui_graphic_driver* hw_driver; /* hdc image information */ - rt_uint32_t width, height; - rt_uint32_t pitch; + rt_uint16_t byte_per_pixel; + rt_uint16_t pitch; + rt_size_t pixel_offset; rt_uint8_t *pixels; }; @@ -43,8 +44,8 @@ static rt_bool_t rtgui_image_hdc_check(struct rtgui_filerw* file) start = rtgui_filerw_tell(file); - /* move to the begining of file */ - rtgui_filerw_seek(file, 0, SEEK_SET); + /* move to the beginning of file */ + rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET); is_HDC = RT_FALSE; if ( rtgui_filerw_read(file, magic, 1, sizeof(magic)) == sizeof(magic) ) @@ -57,7 +58,7 @@ static rt_bool_t rtgui_image_hdc_check(struct rtgui_filerw* file) is_HDC = RT_TRUE; } } - rtgui_filerw_seek(file, start, SEEK_SET); + rtgui_filerw_seek(file, start, RTGUI_FILE_SEEK_SET); return(is_HDC); } @@ -70,55 +71,39 @@ static rt_bool_t rtgui_image_hdc_load(struct rtgui_image* image, struct rtgui_fi hdc = (struct rtgui_image_hdc*) rtgui_malloc(sizeof(struct rtgui_image_hdc)); if (hdc == RT_NULL) return RT_FALSE; + hdc->hw_driver = rtgui_graphic_driver_get_default(); + if (hdc->hw_driver == RT_NULL) { rtgui_free(hdc); return RT_FALSE; } + rtgui_filerw_read(file, (char*)&header, 1, sizeof(header)); /* set image information */ image->w = header[1]; image->h = header[2]; image->engine = &rtgui_image_hdc_engine; - image->data = png; - - if (bit_depth == 16) - png_set_strip_16(png->png_ptr); - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_expand(png->png_ptr); - if (bit_depth < 8) - png_set_expand(png->png_ptr); - if (png_get_valid(png->png_ptr, png->info_ptr, PNG_INFO_tRNS)) - png_set_expand(png->png_ptr); - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png->png_ptr); - - /* Ignore background color */ - - /* set gamma conversion */ - if (png_get_gAMA(png->png_ptr, png->info_ptr, &gamma)) - png_set_gamma(png->png_ptr, (double)2.2, gamma); - - png_read_update_info(png->png_ptr, png->info_ptr); + image->data = hdc; + hdc->filerw = file; + hdc->byte_per_pixel = hdc->hw_driver->byte_per_pixel; + hdc->pitch = image->w * hdc->byte_per_pixel; + hdc->pixel_offset = rtgui_filerw_tell(file); if (load == RT_TRUE) { /* load all pixels */ - png->pixels = rtgui_malloc(image->w * image->h * sizeof(rtgui_color_t)); - if (png->pixels == RT_NULL) + hdc->pixels = rtgui_malloc(image->h * hdc->pitch); + if (hdc->pixels == RT_NULL) { - png_read_end(png->png_ptr, RT_NULL); - - /* destroy png struct */ - png_destroy_info_struct(png->png_ptr, &png->info_ptr); - png_destroy_read_struct(&png->png_ptr, RT_NULL, RT_NULL); - /* release data */ - rtgui_free(png); + rtgui_free(hdc); return RT_FALSE; } - rtgui_image_hdc_process(png->png_ptr, png->info_ptr, png); + rtgui_filerw_read(hdc->filerw, hdc->pixels, 1, image->h * hdc->pitch); + rtgui_filerw_close(hdc->filerw); + hdc->filerw = RT_NULL; + hdc->pixel_offset = 0; } else { - png->pixels = RT_NULL; + hdc->pixels = RT_NULL; } return RT_TRUE; @@ -126,112 +111,138 @@ static rt_bool_t rtgui_image_hdc_load(struct rtgui_image* image, struct rtgui_fi static void rtgui_image_hdc_unload(struct rtgui_image* image) { - struct rtgui_image_hdc* png; + struct rtgui_image_hdc* hdc; if (image != RT_NULL) { - png = (struct rtgui_image_hdc*) image->data; + hdc = (struct rtgui_image_hdc*) image->data; - png_read_end(png->png_ptr, RT_NULL); - - /* destroy png struct */ - png_destroy_info_struct(png->png_ptr, &png->info_ptr); - png_destroy_read_struct(&png->png_ptr, RT_NULL, RT_NULL); - - if (png->pixels != RT_NULL) rtgui_free(png->pixels); + if (hdc->pixels != RT_NULL) rtgui_free(hdc->pixels); + if (hdc->filerw != RT_NULL) + { + rtgui_filerw_close(hdc->filerw); + hdc->filerw = RT_NULL; + } /* release data */ - rtgui_free(png); + rtgui_free(hdc); } } static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect) { - rt_uint16_t x, y, w, h; - rtgui_color_t* ptr; + rt_uint16_t y, w, h; rtgui_color_t foreground; - struct rtgui_image_hdc* png; + struct rtgui_image_hdc* hdc; + rt_uint16_t rect_pitch, hw_pitch; + rtgui_rect_t dc_rect; RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL); - RT_ASSERT(image->data != RT_NULL); - png = (struct rtgui_image_hdc*) image->data; + /* this dc is not visible */ + if (dc->get_visible(dc) != RT_TRUE) return; + hdc = (struct rtgui_image_hdc*) image->data; + RT_ASSERT(hdc != RT_NULL); + + /* transfer logic coordinate to physical coordinate */ + if (dc->type == RTGUI_DC_HW) + { + struct rtgui_dc_hw *hw_dc = (struct rtgui_dc_hw*)dc; + dc_rect = hw_dc->owner->extent; + } + else rtgui_dc_get_rect(dc, &dc_rect); + rtgui_rect_moveto(rect, dc_rect.x1, dc_rect.y1); + + /* the minimum rect */ if (image->w < rtgui_rect_width(*rect)) w = image->w; else w = rtgui_rect_width(*rect); if (image->h < rtgui_rect_height(*rect)) h = image->h; else h = rtgui_rect_height(*rect); + /* get rect pitch */ + rect_pitch = w * hdc->byte_per_pixel; + hw_pitch = hdc->hw_driver->width * hdc->hw_driver->byte_per_pixel; + /* save foreground color */ foreground = rtgui_dc_get_color(dc); - if (png->pixels != RT_NULL) + if (hdc->pixels != RT_NULL) { - ptr = (rtgui_color_t*)png->pixels; - /* draw each point within dc */ - for (y = 0; y < h; y ++) - { - for (x = 0; x < w; x++) - { - /* not alpha */ - if ((*ptr >> 24) != 255) - { - rtgui_dc_set_color(dc, *ptr); - rtgui_dc_draw_point(dc, x + rect->x1, y + rect->y1); - } + if (hdc->hw_driver->get_framebuffer() != RT_NULL) + { + rt_uint8_t* rect_ptr; + rt_uint8_t* hw_ptr; - /* move to next color buffer */ - ptr ++; - } - } + /* get pixel pointer */ + hw_ptr = hdc->hw_driver->get_framebuffer(); + rect_ptr = hdc->pixels; + + /* move hardware pixel pointer */ + hw_ptr += rect->y1 * hdc->pitch + rect->x1 * hdc->byte_per_pixel; + + for (y = 0; y < h; y ++) + { + rt_memcpy(hw_ptr, rect_ptr, rect_pitch); + hw_ptr += hw_pitch; + rect_ptr += rect_pitch; + } + } + else + { + rt_uint8_t* rect_ptr; + + /* get pixel pointer */ + rect_ptr = hdc->pixels; + + for (y = 0; y < h; y ++) + { + hdc->hw_driver->draw_raw_hline(rect_ptr, rect->x1, rect->x2, rect->y1 + y); + rect_ptr += rect_pitch; + } + } } else { - png_bytep row; - png_bytep data; + rt_uint8_t* rect_ptr; + rect_ptr = rtgui_malloc(rect_pitch); + if (rect_ptr == RT_NULL) return; /* no memory */ - row = (png_bytep) rtgui_malloc (png_get_rowbytes(png->png_ptr, png->info_ptr)); - if (row == RT_NULL) return ; + /* seek to the begin of pixel data */ + rtgui_filerw_seek(hdc->filerw, hdc->pixel_offset, RTGUI_FILE_SEEK_SET); - switch (png->info_ptr->color_type) - { - case PNG_COLOR_TYPE_RGBA: - for (y = 0; y < h; y++) - { - png_read_row(png->png_ptr, row, png_bytep_NULL); - for (x = 0; x < w; x++) - { - data = &(row[x * 4]); - if (data[3] != 0) - { - rtgui_dc_set_color(dc, RTGUI_ARGB((255 - data[3]), data[0], data[1], data[2])); - rtgui_dc_draw_point(dc, x + rect->x1, y + rect->y1); - } - } - } + if (hdc->hw_driver->get_framebuffer() != RT_NULL) + { + rt_uint8_t* hw_ptr; - break; + /* get pixel pointer */ + hw_ptr = hdc->hw_driver->get_framebuffer(); + /* move hardware pixel pointer */ + hw_ptr += rect->y1 * hdc->pitch + rect->x1 * hdc->byte_per_pixel; - case PNG_COLOR_TYPE_PALETTE: - for (y = 0; y < h; y++) - { - png_read_row(png->png_ptr, row, png_bytep_NULL); - for (x = 0; x < w; x++) - { - data = &(row[x]); + for (y = 0; y < h; y ++) + { + /* read pixel data */ + if (rtgui_filerw_read(hdc->filerw, rect_ptr, 1, rect_pitch) != rect_pitch) + break; /* read data failed */ - rtgui_dc_set_color(dc, RTGUI_ARGB(0, png->info_ptr->palette[data[0]].red, - png->info_ptr->palette[data[0]].green, - png->info_ptr->palette[data[0]].blue)); - rtgui_dc_draw_point(dc, x + rect->x1, y + rect->y1); - } - } + rt_memcpy(hw_ptr, rect_ptr, rect_pitch); + hw_ptr += hw_pitch; + } + } + else + { + for (y = 0; y < h; y ++) + { + /* read pixel data */ + if (rtgui_filerw_read(hdc->filerw, rect_ptr, 1, rect_pitch) != rect_pitch) + break; /* read data failed */ - default: - break; - }; + hdc->hw_driver->draw_raw_hline(rect_ptr, rect->x1, rect->x2, rect->y1 + y); + } + } - rtgui_free(row); + rtgui_free(rect_ptr); } /* restore foreground */ @@ -240,6 +251,6 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, void rtgui_image_hdc_init() { - /* register png on image system */ + /* register hdc on image system */ rtgui_image_register_engine(&rtgui_image_hdc_engine); }