summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/bmp.c2
-rw-r--r--apps/recorder/jpeg_common.h51
-rw-r--r--apps/recorder/jpeg_load.c32
-rw-r--r--apps/recorder/resize.c47
-rw-r--r--apps/recorder/resize.h11
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
33struct derived_tbl 35struct 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
73struct uint8_yuv {
74 uint8_t y;
75 uint8_t u;
76 uint8_t v;
77};
78
79union uint8_rgbyuv {
80 struct uint8_yuv yuv;
81 struct uint8_rgb rgb;
82};
83
84static 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>
91static 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
156static 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))
521void 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
520void output_row_native(uint32_t row, void * row_in, 550void 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
616const struct custom_format format_native = { 646const 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 = {
622int resize_on_load(struct bitmap *bm, bool dither, struct dim *src, 659int 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
146struct custom_format { 152struct 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