diff options
Diffstat (limited to 'apps/recorder/bmp.c')
-rw-r--r-- | apps/recorder/bmp.c | 87 |
1 files changed, 57 insertions, 30 deletions
diff --git a/apps/recorder/bmp.c b/apps/recorder/bmp.c index d6f61d1c87..819d2e6976 100644 --- a/apps/recorder/bmp.c +++ b/apps/recorder/bmp.c | |||
@@ -173,6 +173,7 @@ static inline void set_rgb_union(struct uint8_rgb *dst, union rgb_union src) | |||
173 | dst->red = src.red; | 173 | dst->red = src.red; |
174 | dst->green = src.green; | 174 | dst->green = src.green; |
175 | dst->blue = src.blue; | 175 | dst->blue = src.blue; |
176 | dst->alpha = 0xff; | ||
176 | } | 177 | } |
177 | 178 | ||
178 | struct bmp_args { | 179 | struct bmp_args { |
@@ -189,6 +190,9 @@ struct bmp_args { | |||
189 | int cur_col; | 190 | int cur_col; |
190 | struct img_part part; | 191 | struct img_part part; |
191 | #endif | 192 | #endif |
193 | /* as read_part_line() goes through the rows it'll set this to true | ||
194 | * if it finds transparency. Initialize to false before calling */ | ||
195 | bool alpha_detected; | ||
192 | }; | 196 | }; |
193 | 197 | ||
194 | static unsigned int read_part_line(struct bmp_args *ba) | 198 | static unsigned int read_part_line(struct bmp_args *ba) |
@@ -233,6 +237,7 @@ static unsigned int read_part_line(struct bmp_args *ba) | |||
233 | #endif | 237 | #endif |
234 | return 0; | 238 | return 0; |
235 | } | 239 | } |
240 | |||
236 | while (ibuf < ba->buf + (BM_MAX_WIDTH << 2)) | 241 | while (ibuf < ba->buf + (BM_MAX_WIDTH << 2)) |
237 | { | 242 | { |
238 | switch (depth) | 243 | switch (depth) |
@@ -274,6 +279,7 @@ static unsigned int read_part_line(struct bmp_args *ba) | |||
274 | component = data & 0xf8; | 279 | component = data & 0xf8; |
275 | component |= component >> 5; | 280 | component |= component >> 5; |
276 | buf->red = component; | 281 | buf->red = component; |
282 | buf->alpha = 0xff; | ||
277 | buf++; | 283 | buf++; |
278 | ibuf += 2; | 284 | ibuf += 2; |
279 | break; | 285 | break; |
@@ -282,13 +288,12 @@ static unsigned int read_part_line(struct bmp_args *ba) | |||
282 | buf->blue = *ibuf++; | 288 | buf->blue = *ibuf++; |
283 | buf->green = *ibuf++; | 289 | buf->green = *ibuf++; |
284 | buf->red = *ibuf++; | 290 | buf->red = *ibuf++; |
285 | if (depth == 32) | 291 | buf->alpha = (depth == 32) ? *ibuf++ : 0xff; |
286 | ibuf++; | 292 | if (buf->alpha != 0xff) ba->alpha_detected = true; |
287 | buf++; | 293 | buf++; |
288 | break; | 294 | break; |
289 | } | 295 | } |
290 | } | 296 | } |
291 | |||
292 | #if !defined(HAVE_LCD_COLOR) && \ | 297 | #if !defined(HAVE_LCD_COLOR) && \ |
293 | ((LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)) || \ | 298 | ((LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)) || \ |
294 | defined(PLUGIN)) | 299 | defined(PLUGIN)) |
@@ -422,41 +427,40 @@ void output_row_8_native(uint32_t row, void * row_in, | |||
422 | } | 427 | } |
423 | #endif /* LCD_PIXELFORMAT */ | 428 | #endif /* LCD_PIXELFORMAT */ |
424 | #elif LCD_DEPTH == 16 | 429 | #elif LCD_DEPTH == 16 |
425 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE | ||
426 | /* M:Robe 500 */ | ||
427 | (void) fb_width; | ||
428 | fb_data *dest = (fb_data *)ctx->bm->data + row; | ||
429 | int delta = 127; | ||
430 | unsigned r, g, b; | ||
431 | for (col = 0; col < ctx->bm->width; col++) { | ||
432 | if (ctx->dither) | ||
433 | delta = DITHERXDY(col,dy); | ||
434 | r = qp->red; | ||
435 | g = qp->green; | ||
436 | b = (qp++)->blue; | ||
437 | r = (31 * r + (r >> 3) + delta) >> 8; | ||
438 | g = (63 * g + (g >> 2) + delta) >> 8; | ||
439 | b = (31 * b + (b >> 3) + delta) >> 8; | ||
440 | *dest = LCD_RGBPACK_LCD(r, g, b); | ||
441 | dest += ctx->bm->height; | ||
442 | } | ||
443 | #else | ||
444 | /* iriver h300, colour iPods, X5 */ | 430 | /* iriver h300, colour iPods, X5 */ |
445 | fb_data *dest = (fb_data *)ctx->bm->data + fb_width * row; | 431 | (void)fb_width; |
432 | fb_data *dest = STRIDE_MAIN((fb_data *)ctx->bm->data + fb_width * row, | ||
433 | (fb_data *)ctx->bm->data + row); | ||
446 | int delta = 127; | 434 | int delta = 127; |
447 | unsigned r, g, b; | 435 | unsigned r, g, b; |
436 | /* setup alpha channel buffer */ | ||
437 | unsigned char *bm_alpha = NULL; | ||
438 | if (ctx->bm->alpha_offset > 0) | ||
439 | bm_alpha = ctx->bm->data + ctx->bm->alpha_offset; | ||
440 | if (bm_alpha) | ||
441 | bm_alpha += ctx->bm->width*row/2; | ||
442 | |||
448 | for (col = 0; col < ctx->bm->width; col++) { | 443 | for (col = 0; col < ctx->bm->width; col++) { |
449 | if (ctx->dither) | 444 | if (ctx->dither) |
450 | delta = DITHERXDY(col,dy); | 445 | delta = DITHERXDY(col,dy); |
451 | r = qp->red; | 446 | r = qp->red; |
452 | g = qp->green; | 447 | g = qp->green; |
453 | b = (qp++)->blue; | 448 | b = qp->blue; |
454 | r = (31 * r + (r >> 3) + delta) >> 8; | 449 | r = (31 * r + (r >> 3) + delta) >> 8; |
455 | g = (63 * g + (g >> 2) + delta) >> 8; | 450 | g = (63 * g + (g >> 2) + delta) >> 8; |
456 | b = (31 * b + (b >> 3) + delta) >> 8; | 451 | b = (31 * b + (b >> 3) + delta) >> 8; |
457 | *dest++ = LCD_RGBPACK_LCD(r, g, b); | 452 | *dest = LCD_RGBPACK_LCD(r, g, b); |
453 | dest += STRIDE_MAIN(1, ctx->bm->height); | ||
454 | if (bm_alpha) { | ||
455 | /* pack alpha channel for 2 pixels into 1 byte */ | ||
456 | unsigned alpha = 255-qp->alpha; | ||
457 | if (col%2) | ||
458 | *bm_alpha++ |= alpha&0xf0; | ||
459 | else | ||
460 | *bm_alpha = alpha>>4; | ||
461 | } | ||
462 | qp++; | ||
458 | } | 463 | } |
459 | #endif | ||
460 | #endif /* LCD_DEPTH */ | 464 | #endif /* LCD_DEPTH */ |
461 | } | 465 | } |
462 | #endif | 466 | #endif |
@@ -480,6 +484,7 @@ int read_bmp_fd(int fd, | |||
480 | int depth, numcolors, compression, totalsize; | 484 | int depth, numcolors, compression, totalsize; |
481 | int ret; | 485 | int ret; |
482 | bool return_size = format & FORMAT_RETURN_SIZE; | 486 | bool return_size = format & FORMAT_RETURN_SIZE; |
487 | bool read_alpha = format & FORMAT_TRANSPARENT; | ||
483 | 488 | ||
484 | unsigned char *bitmap = bm->data; | 489 | unsigned char *bitmap = bm->data; |
485 | struct uint8_rgb palette[256]; | 490 | struct uint8_rgb palette[256]; |
@@ -608,8 +613,14 @@ int read_bmp_fd(int fd, | |||
608 | 613 | ||
609 | if (cformat) | 614 | if (cformat) |
610 | totalsize = cformat->get_size(bm); | 615 | totalsize = cformat->get_size(bm); |
611 | else | 616 | else { |
612 | totalsize = BM_SIZE(bm->width,bm->height,format,remote); | 617 | totalsize = BM_SIZE(bm->width,bm->height,format,remote); |
618 | #ifdef HAVE_REMOTE_LCD | ||
619 | if (!remote) | ||
620 | #endif | ||
621 | if (depth == 32 && read_alpha) /* account for possible 4bit alpha per pixel */ | ||
622 | totalsize += bm->width * bm->height / 2; | ||
623 | } | ||
613 | 624 | ||
614 | if(return_size) | 625 | if(return_size) |
615 | { | 626 | { |
@@ -704,13 +715,21 @@ int read_bmp_fd(int fd, | |||
704 | 715 | ||
705 | memset(bitmap, 0, totalsize); | 716 | memset(bitmap, 0, totalsize); |
706 | 717 | ||
718 | #ifdef HAVE_LCD_COLOR | ||
719 | if (read_alpha && depth == 32) | ||
720 | bm->alpha_offset = totalsize - (bm->width * bm->height / 2); | ||
721 | else | ||
722 | bm->alpha_offset = 0; | ||
723 | #endif | ||
724 | |||
707 | struct bmp_args ba = { | 725 | struct bmp_args ba = { |
708 | .fd = fd, .padded_width = padded_width, .read_width = read_width, | 726 | .fd = fd, .padded_width = padded_width, .read_width = read_width, |
709 | .width = src_dim.width, .depth = depth, .palette = palette, | 727 | .width = src_dim.width, .depth = depth, .palette = palette, |
710 | #if (LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)) && \ | 728 | #if (LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)) && \ |
711 | defined(HAVE_BMP_SCALING) || defined(PLUGIN) | 729 | defined(HAVE_BMP_SCALING) || defined(PLUGIN) |
712 | .cur_row = 0, .cur_col = 0, .part = {0,0} | 730 | .cur_row = 0, .cur_col = 0, .part = {0,0}, |
713 | #endif | 731 | #endif |
732 | .alpha_detected = false, | ||
714 | }; | 733 | }; |
715 | 734 | ||
716 | #if (LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)) && \ | 735 | #if (LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)) && \ |
@@ -759,7 +778,6 @@ int read_bmp_fd(int fd, | |||
759 | return -6; | 778 | return -6; |
760 | } | 779 | } |
761 | #endif | 780 | #endif |
762 | |||
763 | int row; | 781 | int row; |
764 | /* loop to read rows and put them to buffer */ | 782 | /* loop to read rows and put them to buffer */ |
765 | for (row = rset.rowstart; row != rset.rowstop; row += rset.rowstep) { | 783 | for (row = rset.rowstart; row != rset.rowstop; row += rset.rowstep) { |
@@ -858,5 +876,14 @@ int read_bmp_fd(int fd, | |||
858 | } | 876 | } |
859 | #endif | 877 | #endif |
860 | } | 878 | } |
879 | #ifdef HAVE_LCD_COLOR | ||
880 | if (!ba.alpha_detected) | ||
881 | { /* if this has an alpha channel, totalsize accounts for it as well | ||
882 | * subtract if no actual alpha information was found */ | ||
883 | if (bm->alpha_offset > 0) | ||
884 | totalsize -= bm->width*bm->height/2; | ||
885 | bm->alpha_offset = 0; | ||
886 | } | ||
887 | #endif | ||
861 | return totalsize; /* return the used buffer size. */ | 888 | return totalsize; /* return the used buffer size. */ |
862 | } | 889 | } |