diff options
Diffstat (limited to 'apps/recorder/bmp.h')
-rw-r--r-- | apps/recorder/bmp.h | 221 |
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 | ||
41 | struct uint8_rgb { | 37 | struct 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) |
59 | extern const unsigned char dither_matrix[16][16]; | 55 | extern const unsigned char dither_table[16]; |
60 | static 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 | */ | ||
66 | static inline unsigned brightness(struct uint8_rgb color) | 67 | static 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)) |
75 | extern const unsigned short vi_pattern[4]; | 81 | extern const unsigned short vi_pattern[4]; |
76 | static inline unsigned short vi_pat(unsigned int bright) | ||
77 | { | ||
78 | return vi_pattern[bright]; | ||
79 | } | ||
80 | #endif | 82 | #endif |
81 | 83 | ||
82 | static 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 | ||
126 | static 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 | ||
170 | static 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() |