summaryrefslogtreecommitdiff
path: root/apps/recorder/bmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder/bmp.c')
-rw-r--r--apps/recorder/bmp.c87
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
178struct bmp_args { 179struct 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
194static unsigned int read_part_line(struct bmp_args *ba) 198static 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}