From patchwork Sat Sep 29 01:11:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 187989 X-Patchwork-Delegate: agust@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 93A452C00C3 for ; Sat, 29 Sep 2012 11:11:44 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id ADE02283AA; Sat, 29 Sep 2012 03:11:42 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OyaLYwrlhDwl; Sat, 29 Sep 2012 03:11:42 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3FEF428385; Sat, 29 Sep 2012 03:11:41 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D820F28385 for ; Sat, 29 Sep 2012 03:11:38 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5qUC3746-z2l for ; Sat, 29 Sep 2012 03:11:37 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-qc0-f202.google.com (mail-qc0-f202.google.com [209.85.216.202]) by theia.denx.de (Postfix) with ESMTPS id 7F3D728378 for ; Sat, 29 Sep 2012 03:11:33 +0200 (CEST) Received: by qcqs25 with SMTP id s25so415444qcq.3 for ; Fri, 28 Sep 2012 18:11:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=cynKtBFtMfLWPqG76RtovYBz5PGvDBgTVcMNbLNQ+3U=; b=O36Xpl505bp/y0biifwZX39tiZlIZ0DFGe10VYv+HSYvfo5fRqLgzNYEL6Kmda38Te 9mg8ST9PSL7DKElt7oVwYPEzoo/m27117CSPE00VCueJ4siMvr8yY3KzYXbgrAsXApr/ qpiGUkh1Jnm3TiXZ3fI/3pDVnJ8hz/KRLP7DAZRs3fnbGt8C8W2gczhGdvktKDTjjDke QPLrKxUJXyrxYcb3P8KQWTPCQ+Mt2f514N4iRbflmU1Y1OVUL1OP+gsS8A/ZXy7NVzoh jb5ZGzoG4ixJnnh0+49mJSbSjhvP/K7L6n/ybnrRB2uTZubqpxrSx+bsOJzOEG85UxJO nnWg== Received: by 10.236.114.197 with SMTP id c45mr7014935yhh.44.1348881092207; Fri, 28 Sep 2012 18:11:32 -0700 (PDT) Received: from wpzn3.hot.corp.google.com (216-239-44-65.google.com [216.239.44.65]) by gmr-mx.google.com with ESMTPS id l23si2274267yhk.6.2012.09.28.18.11.32 (version=TLSv1/SSLv3 cipher=AES128-SHA); Fri, 28 Sep 2012 18:11:32 -0700 (PDT) Received: from kaka.mtv.corp.google.com (kaka.mtv.corp.google.com [172.22.73.79]) by wpzn3.hot.corp.google.com (Postfix) with ESMTP id F4037100047; Fri, 28 Sep 2012 18:11:31 -0700 (PDT) Received: by kaka.mtv.corp.google.com (Postfix, from userid 121222) id B660A160731; Fri, 28 Sep 2012 18:11:31 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Date: Fri, 28 Sep 2012 18:11:16 -0700 Message-Id: <1348881077-11246-7-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.7.3 In-Reply-To: <1348881077-11246-1-git-send-email-sjg@chromium.org> References: <1348881077-11246-1-git-send-email-sjg@chromium.org> X-Gm-Message-State: ALoCoQnT0jYun3jTdk4QoACvNfBdkAyRJnLIoMwkz3EHzQ7olSsFPhyhtHz03RzLBQ3LSs13NwWW8vfAJyiljbiDpAkH/tCYNCqqqvsqE1Ihvn6Nl47UeedVYFsduZFOyUuEfp+EDUVuI/8QF8d34aTxxXBWZlxWK/fTR/gmEuXTu2t/pSmSM9SSyUa9a0GgTB0raap9gTV/ Cc: Tom Wai-Hong Tam Subject: [U-Boot] [PATCH 6/7] lcd: Implement RLE8 bitmap decoding X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Tom Wai-Hong Tam Add support for drawing compressed RLE8 bitmaps. Reference: http://www.digicamsoft.com/bmp/bmp.html Signed-off-by: Che-Liang Chiou Signed-off-by: Tom Wai-Hong Tam Signed-off-by: Simon Glass Acked-by: Che-Liang Chiou --- README | 5 ++ common/lcd.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 0 deletions(-) diff --git a/README b/README index 5793b0a..40899d9 100644 --- a/README +++ b/README @@ -1440,6 +1440,11 @@ The following options need to be configured: Normally display is black on white background; define CONFIG_SYS_WHITE_ON_BLACK to get it inverted. + CONFIG_LCD_BMP_RLE8 + + Support drawing of RLE8-compressed bitmaps on the LCD. + + - Splash Screen Support: CONFIG_SPLASH_SCREEN If this option is set, the environment is checked for diff --git a/common/lcd.c b/common/lcd.c index 004a6be..68df6d0 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -642,6 +642,136 @@ static void splash_align_axis(int *axis, unsigned long panel_size, } #endif + +#ifdef CONFIG_LCD_BMP_RLE8 + +#define BMP_RLE8_ESCAPE 0 +#define BMP_RLE8_EOL 0 +#define BMP_RLE8_EOBMP 1 +#define BMP_RLE8_DELTA 2 + +static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap, + int cnt) +{ + while (cnt > 0) { + *(*fbp)++ = cmap[*bmap++]; + cnt--; + } +} + +static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt) +{ + ushort *fb = *fbp; + int cnt_8copy = cnt >> 3; + cnt -= cnt_8copy << 3; + while (cnt_8copy > 0) { + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + cnt_8copy--; + } + while (cnt > 0) { + *fb++ = c; + cnt--; + } + (*fbp) = fb; +} + +/* Do not call this function directly, must be called from + * lcd_display_bitmap. + */ +static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, + int x_off, int y_off) +{ + uchar *bmap; + ulong width, height; + ulong cnt, runlen; + int x, y; + int decode = 1; + + width = le32_to_cpu(bmp->header.width); + height = le32_to_cpu(bmp->header.height); + bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset); + + x = 0; + y = height - 1; + + while (decode) { + if (bmap[0] == BMP_RLE8_ESCAPE) { + switch (bmap[1]) { + case BMP_RLE8_EOL: + /* end of line */ + bmap += 2; + x = 0; + y--; + /* 16bpix, 2-byte per pixel, width should *2 */ + fb -= (width * 2 + lcd_line_length); + break; + case BMP_RLE8_EOBMP: + /* end of bitmap */ + decode = 0; + break; + case BMP_RLE8_DELTA: + /* delta run */ + x += bmap[2]; + y -= bmap[3]; + /* 16bpix, 2-byte per pixel, x should *2 */ + fb = (uchar *) (lcd_base + (y + y_off - 1) + * lcd_line_length + (x + x_off) * 2); + bmap += 4; + break; + default: + /* unencoded run */ + runlen = bmap[1]; + bmap += 2; + if (y < height) { + if (x < width) { + if (x + runlen > width) + cnt = width - x; + else + cnt = runlen; + draw_unencoded_bitmap( + (ushort **)&fb, + bmap, cmap, cnt); + } + x += runlen; + } + bmap += runlen; + if (runlen & 1) + bmap++; + } + } else { + /* encoded run */ + if (y < height) { + runlen = bmap[0]; + if (x < width) { + /* aggregate the same code */ + while (bmap[0] == 0xff && + bmap[2] != BMP_RLE8_ESCAPE && + bmap[1] == bmap[3]) { + runlen += bmap[2]; + bmap += 2; + } + if (x + runlen > width) + cnt = width - x; + else + cnt = runlen; + draw_encoded_bitmap((ushort **)&fb, + cmap[bmap[1]], cnt); + } + x += runlen; + } + bmap += 2; + } + } +} +#endif + #if defined(CONFIG_MPC823) || defined(CONFIG_MCC200) #define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++) #else @@ -679,6 +809,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) unsigned long width, height, byte_width; unsigned long pwidth = panel_info.vl_col; unsigned colors, bpix, bmp_bpix; + unsigned long compression; if (!bmp || !((bmp->header.signature[0] == 'B') && (bmp->header.signature[1] == 'M'))) { @@ -691,6 +822,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) height = le32_to_cpu(bmp->header.height); bmp_bpix = le16_to_cpu(bmp->header.bit_count); colors = 1 << bmp_bpix; + compression = le32_to_cpu(bmp->header.compression); bpix = NBITS(panel_info.vl_bpix); @@ -783,6 +915,18 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) switch (bmp_bpix) { case 1: /* pass through */ case 8: +#ifdef CONFIG_LCD_BMP_RLE8 + if (compression == BMP_BI_RLE8) { + if (bpix != 16) { + /* TODO implement render code for bpix != 16 */ + printf("Error: only support 16 bpix"); + return 1; + } + lcd_display_rle8_bitmap(bmp, cmap_base, fb, x, y); + break; + } +#endif + if (bpix != 16) byte_width = width; else