diff options
author | Andrew Mahone <andrew.mahone@gmail.com> | 2009-05-06 04:53:56 +0000 |
---|---|---|
committer | Andrew Mahone <andrew.mahone@gmail.com> | 2009-05-06 04:53:56 +0000 |
commit | eef7945a970e4da69b95c638a44a8ee1a9205430 (patch) | |
tree | ec015938370aaa6e84d3652f914c1766a963582d /apps/recorder | |
parent | f779160de53686e45f57fad882a6d8f8db6360fd (diff) | |
download | rockbox-eef7945a970e4da69b95c638a44a8ee1a9205430.tar.gz rockbox-eef7945a970e4da69b95c638a44a8ee1a9205430.zip |
Move YUV->RGB in JPEG load from before scaler to after scaler. Required change to struct custom_format, so sorted the plugin API as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20856 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/recorder')
-rw-r--r-- | apps/recorder/bmp.c | 2 | ||||
-rw-r--r-- | apps/recorder/jpeg_common.h | 51 | ||||
-rw-r--r-- | apps/recorder/jpeg_load.c | 32 | ||||
-rw-r--r-- | apps/recorder/resize.c | 47 | ||||
-rw-r--r-- | apps/recorder/resize.h | 11 |
5 files changed, 113 insertions, 30 deletions
diff --git a/apps/recorder/bmp.c b/apps/recorder/bmp.c index 403c34d951..f1fc1f83b4 100644 --- a/apps/recorder/bmp.c +++ b/apps/recorder/bmp.c | |||
@@ -603,7 +603,7 @@ int read_bmp_fd(int fd, | |||
603 | { | 603 | { |
604 | if (resize_on_load(bm, dither, &src_dim, &rset, | 604 | if (resize_on_load(bm, dither, &src_dim, &rset, |
605 | bitmap + totalsize, maxsize - totalsize, | 605 | bitmap + totalsize, maxsize - totalsize, |
606 | cformat, store_part_bmp, &ba)) | 606 | cformat, IF_PIX_FMT(0,) store_part_bmp, &ba)) |
607 | return totalsize; | 607 | return totalsize; |
608 | else | 608 | else |
609 | return 0; | 609 | return 0; |
diff --git a/apps/recorder/jpeg_common.h b/apps/recorder/jpeg_common.h index 44bf81e435..061cfc8e64 100644 --- a/apps/recorder/jpeg_common.h +++ b/apps/recorder/jpeg_common.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #ifndef _JPEG_COMMON_H | 28 | #ifndef _JPEG_COMMON_H |
29 | #define _JPEG_COMMON_H | 29 | #define _JPEG_COMMON_H |
30 | 30 | ||
31 | #include "bmp.h" | ||
32 | |||
31 | #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ | 33 | #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ |
32 | #define JPEG_READ_BUF_SIZE 16 | 34 | #define JPEG_READ_BUF_SIZE 16 |
33 | struct derived_tbl | 35 | struct derived_tbl |
@@ -51,6 +53,55 @@ struct derived_tbl | |||
51 | 53 | ||
52 | #define QUANT_TABLE_LENGTH 64 | 54 | #define QUANT_TABLE_LENGTH 64 |
53 | 55 | ||
56 | /* | ||
57 | * Conversion of full 0-255 range YCrCb to RGB: | ||
58 | * |R| |1.000000 -0.000001 1.402000| |Y'| | ||
59 | * |G| = |1.000000 -0.334136 -0.714136| |Pb| | ||
60 | * |B| |1.000000 1.772000 0.000000| |Pr| | ||
61 | * Scaled (yields s15-bit output): | ||
62 | * |R| |128 0 179| |Y | | ||
63 | * |G| = |128 -43 -91| |Cb - 128| | ||
64 | * |B| |128 227 0| |Cr - 128| | ||
65 | */ | ||
66 | #define YFAC 128 | ||
67 | #define RVFAC 179 | ||
68 | #define GUFAC (-43) | ||
69 | #define GVFAC (-91) | ||
70 | #define BUFAC 227 | ||
71 | #define COMPONENT_SHIFT 15 | ||
72 | |||
73 | struct uint8_yuv { | ||
74 | uint8_t y; | ||
75 | uint8_t u; | ||
76 | uint8_t v; | ||
77 | }; | ||
78 | |||
79 | union uint8_rgbyuv { | ||
80 | struct uint8_yuv yuv; | ||
81 | struct uint8_rgb rgb; | ||
82 | }; | ||
83 | |||
84 | static inline int clamp_component(int x) | ||
85 | { | ||
86 | if ((unsigned)x > 255) | ||
87 | x = x < 0 ? 0 : 255; | ||
88 | return x; | ||
89 | } | ||
90 | #include <debug.h> | ||
91 | static inline void yuv_to_rgb(int y, int u, int v, unsigned *r, unsigned *g, unsigned *b) | ||
92 | { | ||
93 | int rv, guv, bu; | ||
94 | y = y * YFAC + (YFAC >> 1); | ||
95 | u = u - 128; | ||
96 | v = v - 128; | ||
97 | rv = RVFAC * v; | ||
98 | guv = GUFAC * u + GVFAC * v; | ||
99 | bu = BUFAC * u; | ||
100 | *r = clamp_component((y + rv) / YFAC); | ||
101 | *g = clamp_component((y + guv) / YFAC); | ||
102 | *b = clamp_component((y + bu) / YFAC); | ||
103 | } | ||
104 | |||
54 | /* for type of Huffman table */ | 105 | /* for type of Huffman table */ |
55 | #define DC_LEN 28 | 106 | #define DC_LEN 28 |
56 | #define AC_LEN 178 | 107 | #define AC_LEN 178 |
diff --git a/apps/recorder/jpeg_load.c b/apps/recorder/jpeg_load.c index 8b2c3f2fef..14aa024fcf 100644 --- a/apps/recorder/jpeg_load.c +++ b/apps/recorder/jpeg_load.c | |||
@@ -153,13 +153,6 @@ INLINE unsigned range_limit(int value) | |||
153 | #endif | 153 | #endif |
154 | } | 154 | } |
155 | 155 | ||
156 | static inline int clamp_component(int x) | ||
157 | { | ||
158 | if ((unsigned)x > 255) | ||
159 | x = x < 0 ? 0 : 255; | ||
160 | return x; | ||
161 | } | ||
162 | |||
163 | /* IDCT implementation */ | 156 | /* IDCT implementation */ |
164 | 157 | ||
165 | 158 | ||
@@ -1810,27 +1803,8 @@ static struct img_part *store_row_jpeg(void *jpeg_args) | |||
1810 | unsigned int xp; | 1803 | unsigned int xp; |
1811 | int yp; | 1804 | int yp; |
1812 | unsigned char *row = out; | 1805 | unsigned char *row = out; |
1813 | if (p_jpeg->blocks > 1) { | 1806 | if (p_jpeg->blocks == 1) |
1814 | for (yp = 0; yp < height; yp++, row += b_width) | 1807 | { |
1815 | { | ||
1816 | unsigned char *px = row; | ||
1817 | for (xp = 0; xp < 1U << p_jpeg->h_scale[1]; | ||
1818 | xp++, px += JPEG_PIX_SZ) | ||
1819 | { | ||
1820 | int y, u, v, rv, guv, bu; | ||
1821 | y = px[0] * YFAC + (YFAC >> 1); | ||
1822 | u = px[1] - 128; | ||
1823 | v = px[2] - 128; | ||
1824 | rv = RVFAC * v; | ||
1825 | guv = GUFAC * u + GVFAC * v; | ||
1826 | bu = BUFAC * u; | ||
1827 | struct uint8_rgb *rgb = (struct uint8_rgb *)px; | ||
1828 | rgb->red = clamp_component((y + rv) / YFAC); | ||
1829 | rgb->green = clamp_component((y + guv) / YFAC); | ||
1830 | rgb->blue = clamp_component((y + bu) / YFAC); | ||
1831 | } | ||
1832 | } | ||
1833 | } else { | ||
1834 | for (yp = 0; yp < height; yp++, row += b_width) | 1808 | for (yp = 0; yp < height; yp++, row += b_width) |
1835 | { | 1809 | { |
1836 | unsigned char *px = row; | 1810 | unsigned char *px = row; |
@@ -2003,7 +1977,7 @@ int read_jpeg_fd(int fd, | |||
2003 | rset.rowstop = bm->height; | 1977 | rset.rowstop = bm->height; |
2004 | rset.rowstep = 1; | 1978 | rset.rowstep = 1; |
2005 | if (resize_on_load(bm, dither, &src_dim, &rset, buf_start, maxsize, cformat, | 1979 | if (resize_on_load(bm, dither, &src_dim, &rset, buf_start, maxsize, cformat, |
2006 | store_row_jpeg, p_jpeg)) | 1980 | IF_PIX_FMT(p_jpeg->blocks == 1 ? 0 : 1,) store_row_jpeg, p_jpeg)) |
2007 | return bm_size; | 1981 | return bm_size; |
2008 | else | 1982 | else |
2009 | return 0; | 1983 | return 0; |
diff --git a/apps/recorder/resize.c b/apps/recorder/resize.c index 7000c448e6..1852519958 100644 --- a/apps/recorder/resize.c +++ b/apps/recorder/resize.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #undef DEBUGF | 59 | #undef DEBUGF |
60 | #define DEBUGF(...) | 60 | #define DEBUGF(...) |
61 | #endif | 61 | #endif |
62 | #include <jpeg_load.h> | ||
62 | 63 | ||
63 | #if CONFIG_CPU == SH7034 | 64 | #if CONFIG_CPU == SH7034 |
64 | /* 16*16->32 bit multiplication is a single instrcution on the SH1 */ | 65 | /* 16*16->32 bit multiplication is a single instrcution on the SH1 */ |
@@ -516,6 +517,35 @@ static inline bool scale_v_linear(struct rowset *rset, | |||
516 | } | 517 | } |
517 | #endif /* HAVE_UPSCALER */ | 518 | #endif /* HAVE_UPSCALER */ |
518 | 519 | ||
520 | #if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN)) | ||
521 | void output_row_native_fromyuv(uint32_t row, void * row_in, | ||
522 | struct scaler_context *ctx) | ||
523 | { | ||
524 | int col; | ||
525 | int fb_width = BM_WIDTH(ctx->bm->width,FORMAT_NATIVE,0); | ||
526 | uint8_t dy = DITHERY(row); | ||
527 | struct uint32_rgb *qp = (struct uint32_rgb *)row_in; | ||
528 | SDEBUGF("output_row: y: %lu in: %p\n",row, row_in); | ||
529 | fb_data *dest = (fb_data *)ctx->bm->data + fb_width * row; | ||
530 | int delta = 127; | ||
531 | unsigned r, g, b, y, u, v; | ||
532 | |||
533 | for (col = 0; col < ctx->bm->width; col++) { | ||
534 | if (ctx->dither) | ||
535 | delta = DITHERXDY(col,dy); | ||
536 | y = SC_MUL(qp->b + ctx->round, ctx->divisor); | ||
537 | u = SC_MUL(qp->g + ctx->round, ctx->divisor); | ||
538 | v = SC_MUL(qp->r + ctx->round, ctx->divisor); | ||
539 | qp++; | ||
540 | yuv_to_rgb(y, u, v, &r, &g, &b); | ||
541 | r = (31 * r + (r >> 3) + delta) >> 8; | ||
542 | g = (63 * g + (g >> 2) + delta) >> 8; | ||
543 | b = (31 * b + (b >> 3) + delta) >> 8; | ||
544 | *dest++ = LCD_RGBPACK_LCD(r, g, b); | ||
545 | } | ||
546 | } | ||
547 | #endif | ||
548 | |||
519 | #if !defined(PLUGIN) || LCD_DEPTH > 1 | 549 | #if !defined(PLUGIN) || LCD_DEPTH > 1 |
520 | void output_row_native(uint32_t row, void * row_in, | 550 | void output_row_native(uint32_t row, void * row_in, |
521 | struct scaler_context *ctx) | 551 | struct scaler_context *ctx) |
@@ -614,7 +644,14 @@ unsigned int get_size_native(struct bitmap *bm) | |||
614 | } | 644 | } |
615 | 645 | ||
616 | const struct custom_format format_native = { | 646 | const struct custom_format format_native = { |
647 | #if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN)) | ||
648 | .output_row = { | ||
649 | output_row_native, | ||
650 | output_row_native_fromyuv | ||
651 | }, | ||
652 | #else | ||
617 | .output_row = output_row_native, | 653 | .output_row = output_row_native, |
654 | #endif | ||
618 | .get_size = get_size_native | 655 | .get_size = get_size_native |
619 | }; | 656 | }; |
620 | #endif | 657 | #endif |
@@ -622,6 +659,7 @@ const struct custom_format format_native = { | |||
622 | int resize_on_load(struct bitmap *bm, bool dither, struct dim *src, | 659 | int resize_on_load(struct bitmap *bm, bool dither, struct dim *src, |
623 | struct rowset *rset, unsigned char *buf, unsigned int len, | 660 | struct rowset *rset, unsigned char *buf, unsigned int len, |
624 | const struct custom_format *format, | 661 | const struct custom_format *format, |
662 | IF_PIX_FMT(int format_index,) | ||
625 | struct img_part* (*store_part)(void *args), | 663 | struct img_part* (*store_part)(void *args), |
626 | void *args) | 664 | void *args) |
627 | { | 665 | { |
@@ -683,10 +721,19 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src, | |||
683 | ctx.src = src; | 721 | ctx.src = src; |
684 | ctx.dither = dither; | 722 | ctx.dither = dither; |
685 | #if !defined(PLUGIN) | 723 | #if !defined(PLUGIN) |
724 | #if defined(HAVE_LCD_COLOR) && defined(HAVE_JPEG) | ||
725 | ctx.output_row = format_index ? output_row_native_fromyuv | ||
726 | : output_row_native; | ||
727 | #else | ||
686 | ctx.output_row = output_row_native; | 728 | ctx.output_row = output_row_native; |
729 | #endif | ||
687 | if (format) | 730 | if (format) |
688 | #endif | 731 | #endif |
732 | #if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN)) | ||
733 | ctx.output_row = format->output_row[format_index]; | ||
734 | #else | ||
689 | ctx.output_row = format->output_row; | 735 | ctx.output_row = format->output_row; |
736 | #endif | ||
690 | #ifdef HAVE_UPSCALER | 737 | #ifdef HAVE_UPSCALER |
691 | if (sw > dw) | 738 | if (sw > dw) |
692 | { | 739 | { |
diff --git a/apps/recorder/resize.h b/apps/recorder/resize.h index de9e8a9ab0..f7cda15254 100644 --- a/apps/recorder/resize.h +++ b/apps/recorder/resize.h | |||
@@ -143,8 +143,18 @@ struct scaler_context { | |||
143 | bool (*h_scaler)(void*,struct scaler_context*, bool); | 143 | bool (*h_scaler)(void*,struct scaler_context*, bool); |
144 | }; | 144 | }; |
145 | 145 | ||
146 | #if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN)) | ||
147 | #define IF_PIX_FMT(...) __VA_ARGS__ | ||
148 | #else | ||
149 | #define IF_PIX_FMT(...) | ||
150 | #endif | ||
151 | |||
146 | struct custom_format { | 152 | struct custom_format { |
153 | #if defined(HAVE_LCD_COLOR) | ||
154 | void (*output_row[2])(uint32_t,void*,struct scaler_context*); | ||
155 | #else | ||
147 | void (*output_row)(uint32_t,void*,struct scaler_context*); | 156 | void (*output_row)(uint32_t,void*,struct scaler_context*); |
157 | #endif | ||
148 | unsigned int (*get_size)(struct bitmap *bm); | 158 | unsigned int (*get_size)(struct bitmap *bm); |
149 | }; | 159 | }; |
150 | 160 | ||
@@ -161,6 +171,7 @@ int resize_on_load(struct bitmap *bm, bool dither, | |||
161 | struct dim *src, struct rowset *tmp_row, | 171 | struct dim *src, struct rowset *tmp_row, |
162 | unsigned char *buf, unsigned int len, | 172 | unsigned char *buf, unsigned int len, |
163 | const struct custom_format *cformat, | 173 | const struct custom_format *cformat, |
174 | IF_PIX_FMT(int format_index,) | ||
164 | struct img_part* (*store_part)(void *args), | 175 | struct img_part* (*store_part)(void *args), |
165 | void *args); | 176 | void *args); |
166 | 177 | ||