summaryrefslogtreecommitdiff
path: root/apps/recorder/bmp.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/recorder/bmp.h')
-rw-r--r--apps/recorder/bmp.h221
1 files changed, 116 insertions, 105 deletions
diff --git a/apps/recorder/bmp.h b/apps/recorder/bmp.h
index d1b1d7f3ed..273e178bc9 100644
--- a/apps/recorder/bmp.h
+++ b/apps/recorder/bmp.h
@@ -32,11 +32,7 @@
32 32
33#define IMG_NORESIZE 0 33#define IMG_NORESIZE 0
34#define IMG_RESIZE 1 34#define IMG_RESIZE 1
35#if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) 35#define BM_MAX_WIDTH (((LCD_WIDTH) + 7) & ~7)
36#define MAX_WIDTH 8
37#else
38#define MAX_WIDTH LCD_WIDTH
39#endif
40 36
41struct uint8_rgb { 37struct uint8_rgb {
42 uint8_t blue; 38 uint8_t blue;
@@ -56,129 +52,144 @@ struct rowset {
56}; 52};
57 53
58#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 54#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
59extern const unsigned char dither_matrix[16][16]; 55extern const unsigned char dither_table[16];
60static inline unsigned char dither_mat(unsigned int x, unsigned int y) 56#define DITHERY(y) (dither_table[(y) & 15] & 0xAA)
61{ 57#define DITHERX(x) (dither_table[(x) & 15])
62 return dither_matrix[y][x]; 58#define DITHERXDY(x,dy) (DITHERX(x) ^ dy)
63} 59#define DITHERDXY(dx,y) (dx ^ DITHERY(y))
60#define DITHERXY(x,y) (DITHERX(x) ^ DITHERY(y))
64#endif 61#endif
65 62
63/* The /256 version has a mean squared variance from YUV luma of <1 grey level.
64 The /8 version is a good deal less accurate, but sufficient on mono as we
65 don't support HQ output or dithering there, yet.
66*/
66static inline unsigned brightness(struct uint8_rgb color) 67static inline unsigned brightness(struct uint8_rgb color)
67{ 68{
68 return (3 * (unsigned)color.red + 6 * (unsigned)color.green 69#if LCD_DEPTH > 1
69 + (unsigned)color.blue) / 10; 70 return (77 * (unsigned)color.red + 150 * (unsigned)color.green
71 + 29 * (unsigned)color.blue) / 256;
72#else
73 return (2 * (unsigned)color.red + 5 * (unsigned)color.green
74 + (unsigned)color.blue) / 8;
75#endif
70} 76}
71 77
72#if ((LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)) \ 78#if ((LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)) \
73 || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH == 2) \ 79 || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH == 2) \
74 && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED)) 80 && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED))
75extern const unsigned short vi_pattern[4]; 81extern const unsigned short vi_pattern[4];
76static inline unsigned short vi_pat(unsigned int bright)
77{
78 return vi_pattern[bright];
79}
80#endif 82#endif
81 83
82static inline int get_fb_height(struct bitmap *bm, bool remote) 84/* Number of rows of data in a mono bitmap height pixels tall */
83{ 85#define MONO_BM_HEIGHT(height) (((height) + 7) >> 3)
84 const int height = bm->height; 86
85#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 87/* Number of rows of datain a LCD native bitmap height pixels tall */
86 const int format = bm->format; 88#if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
89#if LCD_DEPTH == 1 || \
90 (LCD_DEPTH == 2 && LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
91#define LCD_BM_HEIGHT(height) (((height) + 7) >> 3)
92#elif LCD_DEPTH == 2 && LCD_PIXELFORMAT == VERTICAL_PACKING
93#define LCD_BM_HEIGHT(height) (((height) + 3) >> 2)
94#else
95#define LCD_BM_HEIGHT(height) (height)
87#endif 96#endif
88 int dst_height;
89 97
90#if !defined(HAVE_REMOTE_LCD) || \ 98/* Number of rows of data in a remote native bitmap height pixels tall. */
91 (defined(HAVE_REMOTE_LCD) &&(LCD_REMOTE_DEPTH == 1)) 99#ifdef HAVE_REMOTE_LCD
92 (void) remote; 100#if LCD_REMOTE_DEPTH == 1 || \
101 (LCD_REMOTE_DEPTH == 2 && LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED)
102#define LCD_REMOTE_BM_HEIGHT(height) (((height) + 7) >> 3)
103#elif LCD_REMOTE_DEPTH == 2 && LCD_REMOTE_PIXELFORMAT == VERTICAL_PACKING
104#define LCD_REMOTE_BM_HEIGHT(height) (((height) + 3) >> 2)
105#else
106#define LCD_REMOTE_BM_HEIGHT(height) (height)
107#endif
108#define NATIVE_BM_HEIGHT(height,remote) ((remote) ? \
109 LCD_REMOTE_BM_HEIGHT(height) : LCD_BM_HEIGHT(height))
110#else
111#define NATIVE_BM_HEIGHT(height,remote) LCD_BM_HEIGHT(height)
93#endif 112#endif
94 113
95#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 114/* Convenience macro to calculate rows based on height, remote vs main LCD,
96 if (format == FORMAT_NATIVE) { 115 and format
97#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 116*/
98 if (remote) { 117#define BM_HEIGHT(height,format,remote) ((format) == FORMAT_MONO ? \
99#if (LCD_REMOTE_DEPTH == 2) && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) 118 MONO_BM_HEIGHT(height) : NATIVE_BM_HEIGHT(height,remote))
100 dst_height = (height + 7) >> 3; 119#else
101#endif /* LCD_REMOTE_DEPTH / LCD_REMOTE_PIXELFORMAT */ 120#define BM_HEIGHT(height,format,remote) MONO_BM_HEIGHT(height)
102 } else 121#endif
103#endif /* defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 */
104 {
105#if LCD_DEPTH == 2
106#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
107 dst_height = height;
108#elif LCD_PIXELFORMAT == VERTICAL_PACKING
109 dst_height = (height + 3) >> 2;
110#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
111 dst_height = (height + 7) >> 3;
112#endif /* LCD_PIXELFORMAT */
113#elif LCD_DEPTH == 16
114 dst_height = height;
115#endif /* LCD_DEPTH */
116 }
117 } else
118#endif /* (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) */
119 {
120 dst_height = (height + 7) >> 3;
121 }
122
123 return dst_height;
124}
125 122
126static inline int get_fb_width(struct bitmap *bm, bool remote) 123/* Number of data elements in a mono bitmap width pixels wide */
127{ 124#define MONO_BM_WIDTH(width) (width)
128 const int width = bm->width; 125
129#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 126/* Number of data elements in a LCD native bitmap width pixels wide */
130 const int format = bm->format; 127#if LCD_DEPTH > 1
128#if LCD_DEPTH == 2 && LCD_PIXELFORMAT == HORIZONTAL_PACKING
129#define LCD_BM_WIDTH(width) (((width) + 3) >> 2)
130#else
131#define LCD_BM_WIDTH(width) (width)
131#endif 132#endif
132 int dst_width;
133 133
134#if !defined(HAVE_REMOTE_LCD) || \ 134/* Number of data elements in a remote native bitmap width pixels wide */
135 (defined(HAVE_REMOTE_LCD) &&(LCD_REMOTE_DEPTH == 1)) 135#ifdef HAVE_LCD_REMOTE
136 (void) remote; 136#if LCD_REMOTE_DEPTH == 2 && LCD_REMOTE_PIXELFORMAT == HORIZONTAL_PACKING
137#define LCD_REMOTE_BM_WIDTH(width) (((width) + 3) >> 2)
138#else
139#define LCD_REMOTE_BM_WIDTH(width) (width)
140#endif
141#define NATIVE_BM_WIDTH(width,remote) ((remote) ? \
142 LCD_REMOTE_BM_WIDTH(width) : LCD_BM_WIDTH(width))
143#else
144#define NATIVE_BM_WIDTH(width,remote) LCD_BM_WIDTH(width)
137#endif 145#endif
138 146
139#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 147/* Convenience macro to calculate elements based on height, remote vs native
140 if (format == FORMAT_NATIVE) { 148 main LCD, and format
141#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 149*/
142 if (remote) { 150#define BM_WIDTH(width,format,remote) ((format) == FORMAT_MONO ? \
143#if (LCD_REMOTE_DEPTH == 2) && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) 151 MONO_BM_WIDTH(width) : NATIVE_BM_WIDTH(width,remote))
144 dst_width = width; 152#else
145#endif /* LCD_REMOTE_DEPTH / LCD_REMOTE_PIXELFORMAT */ 153#define BM_WIDTH(width,format,remote) MONO_BM_WIDTH(width)
146 } else 154#endif
147#endif /* defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 */
148 {
149#if LCD_DEPTH == 2
150#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
151 dst_width = (width + 3) >> 2;
152#elif LCD_PIXELFORMAT == VERTICAL_PACKING
153 dst_width = width;
154#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
155 dst_width = width;
156#endif /* LCD_PIXELFORMAT */
157#elif LCD_DEPTH == 16
158 dst_width = width;
159#endif /* LCD_DEPTH */
160 }
161 } else
162#endif /* (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) */
163 {
164 dst_width = width;
165 }
166
167 return dst_width;
168}
169 155
170static inline int get_totalsize(struct bitmap *bm, bool remote) 156/* Size in bytes of a mono bitmap of dimensions width*height */
171{ 157#define MONO_BM_SIZE(width,height) (MONO_BM_WIDTH(width) * \
172 int sz; 158 MONO_BM_HEIGHT(height) * FB_DATA_SZ)
173#ifdef HAVE_REMOTE_LCD
174 if (remote && sizeof(fb_data) != sizeof(fb_remote_data))
175 sz = sizeof(fb_remote_data);
176 else
177#endif /* LCD_REMOTE_DEPTH / LCD_REMOTE_PIXELFORMAT */
178 sz = sizeof(fb_data);
179 159
180 return get_fb_width(bm, remote) * get_fb_height(bm, remote) * sz; 160/* Size in bytes of a native bitmap of dimensions width*height */
181} 161#if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
162#if defined(HAVE_REMOTE_LCD) && FB_DATA_SZ != FB_RDATA_SZ
163#define NATIVE_BM_SIZE(width,height,format,remote) \
164 (((remote) ? FB_RDATA_SZ : FB_DATA_SZ) * BM_WIDTH(width,format,remote) \
165 * BM_HEIGHT(height,format,remote))
166#else
167#define NATIVE_BM_SIZE(width,height,format,remote) \
168 (FB_DATA_SZ * BM_WIDTH(width,format,remote) * \
169 BM_HEIGHT(height,format,remote))
170#endif
171
172/* Convenience macro to calculate size in bytes based on height, remote vs
173 main LCD, and format
174*/
175#define BM_SIZE(width,height,format,remote) (((format) == FORMAT_MONO) ? \
176 MONO_BM_SIZE(width,height) : NATIVE_BM_SIZE(width,height,format,remote))
177#else
178#define BM_SIZE(width,height,format,remote) MONO_BM_SIZE(width,height)
179#endif
180
181/* Size in bytes needed to load and scale a bitmap with target size up to
182 width*height, including overhead to allow for buffer alignment.
183*/
184#ifdef HAVE_LCD_COLOR
185#define BM_SCALED_SIZE(width,height,format,remote) \
186 (BM_SIZE(width,height,format,remote) + \
187 (remote ? 0 : BM_WIDTH(width,format,remote) * sizeof(uint32_t) * 9 + 3))
188#else
189#define BM_SCALED_SIZE(width,height,format,remote) \
190 (BM_SIZE(width,height,format,remote) + \
191 (width * sizeof(uint32_t) * 3 + 3))
192#endif
182 193
183/********************************************************************* 194/*********************************************************************
184 * read_bmp_file() 195 * read_bmp_file()