summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/recorder/bmp.c193
1 files changed, 123 insertions, 70 deletions
diff --git a/apps/recorder/bmp.c b/apps/recorder/bmp.c
index 130505b9bc..96b915f840 100644
--- a/apps/recorder/bmp.c
+++ b/apps/recorder/bmp.c
@@ -35,6 +35,9 @@
35#include "inttypes.h" 35#include "inttypes.h"
36#include "debug.h" 36#include "debug.h"
37#include "lcd.h" 37#include "lcd.h"
38#ifdef HAVE_REMOTE_LCD
39#include "lcd-remote.h"
40#endif
38#include "file.h" 41#include "file.h"
39#include "config.h" 42#include "config.h"
40#include "system.h" 43#include "system.h"
@@ -85,7 +88,7 @@ static const unsigned char bitfields[3][12] = {
85 { 0x00,0x00,0xff,0, 0x00,0xff,0x00,0, 0xff,0x00,0x00,0 }, /* 32 bit */ 88 { 0x00,0x00,0xff,0, 0x00,0xff,0x00,0, 0xff,0x00,0x00,0 }, /* 32 bit */
86}; 89};
87 90
88#if LCD_DEPTH > 1 91#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
89/* canonical ordered dither matrix */ 92/* canonical ordered dither matrix */
90static const unsigned char dither_matrix[16][16] = { 93static const unsigned char dither_matrix[16][16] = {
91 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, 94 { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
@@ -107,6 +110,13 @@ static const unsigned char dither_matrix[16][16] = {
107}; 110};
108#endif 111#endif
109 112
113#if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH == 2) \
114 && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED)
115static const fb_remote_data remote_pattern[4] = {
116 0x0101, 0x0100, 0x0001, 0x0000
117};
118#endif
119
110/* little endian functions */ 120/* little endian functions */
111static inline unsigned readshort(uint16_t *value) 121static inline unsigned readshort(uint16_t *value)
112{ 122{
@@ -147,10 +157,21 @@ int read_bmp_file(char* filename,
147 unsigned char *bitmap = bm->data; 157 unsigned char *bitmap = bm->data;
148 uint32_t bmpbuf[LCD_WIDTH]; /* Buffer for one line */ 158 uint32_t bmpbuf[LCD_WIDTH]; /* Buffer for one line */
149 uint32_t palette[256]; 159 uint32_t palette[256];
150#if LCD_DEPTH > 1 160#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
151 bool transparent = false; 161 bool transparent = false;
152 bool dither = false; 162 bool dither = false;
153 163#ifdef HAVE_REMOTE_LCD
164 bool remote = false;
165
166 if (format & FORMAT_REMOTE) {
167 remote = true;
168#if LCD_REMOTE_DEPTH == 1
169 format = FORMAT_MONO;
170#else
171 format &= ~FORMAT_REMOTE;
172#endif
173 }
174#endif /* HAVE_REMOTE_LCD */
154 if (format & FORMAT_TRANSPARENT) { 175 if (format & FORMAT_TRANSPARENT) {
155 transparent = true; 176 transparent = true;
156 format &= ~FORMAT_TRANSPARENT; 177 format &= ~FORMAT_TRANSPARENT;
@@ -162,7 +183,7 @@ int read_bmp_file(char* filename,
162#else 183#else
163 184
164 (void)format; 185 (void)format;
165#endif 186#endif /* (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) */
166 187
167 fd = open(filename, O_RDONLY); 188 fd = open(filename, O_RDONLY);
168 189
@@ -204,7 +225,7 @@ int read_bmp_file(char* filename,
204 depth = readshort(&bmph.bit_count); 225 depth = readshort(&bmph.bit_count);
205 padded_width = ((width * depth + 31) / 8) & ~3; /* 4-byte boundary aligned */ 226 padded_width = ((width * depth + 31) / 8) & ~3; /* 4-byte boundary aligned */
206 227
207#if LCD_DEPTH > 1 228#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
208 if (format == FORMAT_ANY) { 229 if (format == FORMAT_ANY) {
209 if (depth == 1) 230 if (depth == 1)
210 format = FORMAT_MONO; 231 format = FORMAT_MONO;
@@ -212,28 +233,39 @@ int read_bmp_file(char* filename,
212 format = FORMAT_NATIVE; 233 format = FORMAT_NATIVE;
213 } 234 }
214 bm->format = format; 235 bm->format = format;
215#endif 236#endif /* (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) */
216 /* returning image size */ 237 /* returning image size */
217 bm->width = width; 238 bm->width = width;
218 bm->height = height; 239 bm->height = height;
219 240
220#if LCD_DEPTH > 1 241#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
221 if (format == FORMAT_NATIVE) { 242 if (format == FORMAT_NATIVE) {
243#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
244 if (remote) {
245#if (LCD_REMOTE_DEPTH == 2) && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED)
246 dst_width = width;
247 dst_height = (height + 7) / 8;
248#endif /* LCD_REMOTE_DEPTH / LCD_REMOTE_PIXELFORMAT */
249 totalsize = dst_width * dst_height * sizeof(fb_remote_data);
250 } else
251#endif /* defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 */
252 {
222#if LCD_DEPTH == 2 253#if LCD_DEPTH == 2
223#if LCD_PIXELFORMAT == VERTICAL_PACKING 254#if LCD_PIXELFORMAT == VERTICAL_PACKING
224 dst_width = width; 255 dst_width = width;
225 dst_height = (height + 3) / 4; 256 dst_height = (height + 3) / 4;
226#else /* LCD_PIXELFORMAT == HORIZONTAL_PACKING */ 257#else /* LCD_PIXELFORMAT == HORIZONTAL_PACKING */
227 dst_width = (width + 3) / 4; 258 dst_width = (width + 3) / 4;
228 dst_height = height; 259 dst_height = height;
229#endif /* LCD_PIXELFORMAT */ 260#endif /* LCD_PIXELFORMAT */
230#elif LCD_DEPTH == 16 261#elif LCD_DEPTH == 16
231 dst_width = width; 262 dst_width = width;
232 dst_height = height; 263 dst_height = height;
233#endif /* LCD_DEPTH */ 264#endif /* LCD_DEPTH */
234 totalsize = dst_width * dst_height * sizeof(fb_data); 265 totalsize = dst_width * dst_height * sizeof(fb_data);
266 }
235 } else 267 } else
236#endif /* LCD_DEPTH > 1 */ 268#endif /* (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) */
237 { 269 {
238 dst_width = width; 270 dst_width = width;
239 dst_height = (height + 7) / 8; 271 dst_height = (height + 7) / 8;
@@ -270,7 +302,10 @@ int read_bmp_file(char* filename,
270 case 16: 302 case 16:
271#if LCD_DEPTH >= 16 303#if LCD_DEPTH >= 16
272 /* don't dither 16 bit BMP to LCD with same or larger depth */ 304 /* don't dither 16 bit BMP to LCD with same or larger depth */
273 dither = false; 305#ifdef HAVE_REMOTE_LCD
306 if (!remote)
307#endif
308 dither = false;
274#endif 309#endif
275 if (compression == 0) { /* BI_RGB, i.e. 15 bit */ 310 if (compression == 0) { /* BI_RGB, i.e. 15 bit */
276 depth = 15; 311 depth = 15;
@@ -303,10 +338,7 @@ int read_bmp_file(char* filename,
303 /* Search to the beginning of the image data */ 338 /* Search to the beginning of the image data */
304 lseek(fd, (off_t)readlong(&bmph.off_bits), SEEK_SET); 339 lseek(fd, (off_t)readlong(&bmph.off_bits), SEEK_SET);
305 340
306#if LCD_DEPTH >= 8 341 memset(bitmap, 0, totalsize);
307 if (format == FORMAT_MONO)
308#endif
309 memset(bitmap, 0, totalsize);
310 342
311 /* loop to read rows and put them to buffer */ 343 /* loop to read rows and put them to buffer */
312 for (row = height - 1; row >= 0; row--) { 344 for (row = height - 1; row >= 0; row--) {
@@ -422,65 +454,86 @@ int read_bmp_file(char* filename,
422 454
423 /* Convert to destination format */ 455 /* Convert to destination format */
424 qp = (union rgb_union *)bmpbuf; 456 qp = (union rgb_union *)bmpbuf;
425#if LCD_DEPTH > 1 457#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
426 if (format == FORMAT_NATIVE) { 458 if (format == FORMAT_NATIVE) {
459#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
460 if (remote) {
461#if (LCD_REMOTE_DEPTH == 2) && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED)
462 fb_remote_data *dest = (fb_remote_data *)bitmap
463 + dst_width * (row / 8);
464 int shift = row & 7;
465 int delta = 127;
466 unsigned bright;
467
468 for (col = 0; col < width; col++) {
469 if (dither)
470 delta = dither_matrix[row & 0xf][col & 0xf];
471 bright = brightness(*qp++);
472 bright = (3 * bright + (bright >> 6) + delta) >> 8;
473 *dest++ |= remote_pattern[bright] << shift;
474 }
475#endif /* LCD_REMOTE_DEPTH / LCD_REMOTE_PIXELFORMAT */
476 } else
477#endif /* defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 */
478 {
427#if LCD_DEPTH == 2 479#if LCD_DEPTH == 2
428#if LCD_PIXELFORMAT == VERTICAL_PACKING 480#if LCD_PIXELFORMAT == VERTICAL_PACKING
429 /* iriver H1x0 */ 481 /* iriver H1x0 */
430 fb_data *dest = (fb_data *)bitmap + dst_width * (row / 4); 482 fb_data *dest = (fb_data *)bitmap + dst_width * (row / 4);
431 int shift = 2 * (row & 3); 483 int shift = 2 * (row & 3);
432 int delta = 127; 484 int delta = 127;
433 unsigned bright; 485 unsigned bright;
434 486
435 for (col = 0; col < width; col++) { 487 for (col = 0; col < width; col++) {
436 if (dither) 488 if (dither)
437 delta = dither_matrix[row & 0xf][col & 0xf]; 489 delta = dither_matrix[row & 0xf][col & 0xf];
438 bright = brightness(*qp++); 490 bright = brightness(*qp++);
439 bright = (3 * bright + (bright >> 6) + delta) >> 8; 491 bright = (3 * bright + (bright >> 6) + delta) >> 8;
440 *dest++ |= (~bright & 3) << shift; 492 *dest++ |= (~bright & 3) << shift;
441 } 493 }
442#else /* LCD_PIXELFORMAT == HORIZONTAL_PACKING */ 494#else /* LCD_PIXELFORMAT == HORIZONTAL_PACKING */
443 /* greyscale iPods */ 495 /* greyscale iPods */
444 fb_data *dest = (fb_data *)bitmap + dst_width * row; 496 fb_data *dest = (fb_data *)bitmap + dst_width * row;
445 int shift = 6; 497 int shift = 6;
446 int delta = 127; 498 int delta = 127;
447 unsigned bright; 499 unsigned bright;
448 unsigned data = 0; 500 unsigned data = 0;
449 501
450 for (col = 0; col < width; col++) { 502 for (col = 0; col < width; col++) {
451 if (dither) 503 if (dither)
452 delta = dither_matrix[row & 0xf][col & 0xf]; 504 delta = dither_matrix[row & 0xf][col & 0xf];
453 bright = brightness(*qp++); 505 bright = brightness(*qp++);
454 bright = (3 * bright + (bright >> 6) + delta) >> 8; 506 bright = (3 * bright + (bright >> 6) + delta) >> 8;
455 data |= (~bright & 3) << shift; 507 data |= (~bright & 3) << shift;
456 shift -= 2; 508 shift -= 2;
457 if (shift < 0) { 509 if (shift < 0) {
458 *dest++ = data; 510 *dest++ = data;
459 data = 0; 511 data = 0;
460 shift = 6; 512 shift = 6;
513 }
461 } 514 }
462 } 515 if (shift < 6)
463 if (shift < 6) 516 *dest++ = data;
464 *dest++ = data;
465#endif /* LCD_PIXELFORMAT */ 517#endif /* LCD_PIXELFORMAT */
466#elif LCD_DEPTH == 16 518#elif LCD_DEPTH == 16
467 /* iriver h300, colour iPods, X5 */ 519 /* iriver h300, colour iPods, X5 */
468 fb_data *dest = (fb_data *)bitmap + dst_width * row; 520 fb_data *dest = (fb_data *)bitmap + dst_width * row;
469 int delta = 127; 521 int delta = 127;
470 unsigned r, g, b; 522 unsigned r, g, b;
471 523
472 for (col = 0; col < width; col++) { 524 for (col = 0; col < width; col++) {
473 if (dither) 525 if (dither)
474 delta = dither_matrix[row & 0xf][col & 0xf]; 526 delta = dither_matrix[row & 0xf][col & 0xf];
475 q0 = *qp++; 527 q0 = *qp++;
476 r = (31 * q0.red + (q0.red >> 3) + delta) >> 8; 528 r = (31 * q0.red + (q0.red >> 3) + delta) >> 8;
477 g = (63 * q0.green + (q0.green >> 2) + delta) >> 8; 529 g = (63 * q0.green + (q0.green >> 2) + delta) >> 8;
478 b = (31 * q0.blue + (q0.blue >> 3) + delta) >> 8; 530 b = (31 * q0.blue + (q0.blue >> 3) + delta) >> 8;
479 *dest++ = LCD_RGBPACK_LCD(r, g, b); 531 *dest++ = LCD_RGBPACK_LCD(r, g, b);
480 } 532 }
481#endif /* LCD_DEPTH */ 533#endif /* LCD_DEPTH */
534 }
482 } else 535 } else
483#endif /* LCD_DEPTH > 1 */ 536#endif /* (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) */
484 { 537 {
485 p = bitmap + dst_width * (row / 8); 538 p = bitmap + dst_width * (row / 8);
486 mask = 1 << (row & 7); 539 mask = 1 << (row & 7);