diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-03-08 23:50:55 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-03-08 23:50:55 +0000 |
commit | 8c6920e34393c3982d4333c13c6ebb26f545c842 (patch) | |
tree | c1403aff0405f4a1464a739b313ffb8431b245ac /apps/player/bmp.c | |
parent | 9b939a615d29b22ceab0da881b641f45381660b3 (diff) | |
download | rockbox-8c6920e34393c3982d4333c13c6ebb26f545c842.tar.gz rockbox-8c6920e34393c3982d4333c13c6ebb26f545c842.zip |
Revert accidental tree commit. Sorry for that.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16574 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/player/bmp.c')
-rw-r--r-- | apps/player/bmp.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/apps/player/bmp.c b/apps/player/bmp.c new file mode 100644 index 0000000000..290880c0f7 --- /dev/null +++ b/apps/player/bmp.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | /* | ||
21 | 2008-02-24 Jens Arnold: minimalistic version for charcell displays | ||
22 | */ | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <string.h> | ||
27 | #include "inttypes.h" | ||
28 | #include "debug.h" | ||
29 | #include "lcd.h" | ||
30 | #include "file.h" | ||
31 | #include "config.h" | ||
32 | #include "system.h" | ||
33 | #include "bmp.h" | ||
34 | #include "lcd.h" | ||
35 | |||
36 | #ifdef __GNUC__ | ||
37 | #define STRUCT_PACKED __attribute__((packed)) | ||
38 | #else | ||
39 | #define STRUCT_PACKED | ||
40 | #pragma pack (push, 2) | ||
41 | #endif | ||
42 | |||
43 | /* BMP header structure */ | ||
44 | struct bmp_header { | ||
45 | uint16_t type; /* signature - 'BM' */ | ||
46 | uint32_t size; /* file size in bytes */ | ||
47 | uint16_t reserved1; /* 0 */ | ||
48 | uint16_t reserved2; /* 0 */ | ||
49 | uint32_t off_bits; /* offset to bitmap */ | ||
50 | uint32_t struct_size; /* size of this struct (40) */ | ||
51 | int32_t width; /* bmap width in pixels */ | ||
52 | int32_t height; /* bmap height in pixels */ | ||
53 | uint16_t planes; /* num planes - always 1 */ | ||
54 | uint16_t bit_count; /* bits per pixel */ | ||
55 | uint32_t compression; /* compression flag */ | ||
56 | uint32_t size_image; /* image size in bytes */ | ||
57 | int32_t x_pels_per_meter; /* horz resolution */ | ||
58 | int32_t y_pels_per_meter; /* vert resolution */ | ||
59 | uint32_t clr_used; /* 0 -> color table size */ | ||
60 | uint32_t clr_important; /* important color count */ | ||
61 | } STRUCT_PACKED; | ||
62 | |||
63 | union rgb_union { | ||
64 | struct { /* Little endian */ | ||
65 | unsigned char blue; | ||
66 | unsigned char green; | ||
67 | unsigned char red; | ||
68 | unsigned char reserved; | ||
69 | }; | ||
70 | uint32_t raw; | ||
71 | }; | ||
72 | |||
73 | |||
74 | /* little endian functions */ | ||
75 | static inline unsigned readshort(uint16_t *value) | ||
76 | { | ||
77 | unsigned char* bytes = (unsigned char*) value; | ||
78 | return (unsigned)bytes[0] | ((unsigned)bytes[1] << 8); | ||
79 | } | ||
80 | |||
81 | static inline uint32_t readlong(uint32_t *value) | ||
82 | { | ||
83 | unsigned char* bytes = (unsigned char*) value; | ||
84 | return (uint32_t)bytes[0] | ((uint32_t)bytes[1] << 8) | | ||
85 | ((uint32_t)bytes[2] << 16) | ((uint32_t)bytes[3] << 24); | ||
86 | } | ||
87 | |||
88 | static inline unsigned brightness(union rgb_union color) | ||
89 | { | ||
90 | return (3 * (unsigned)color.red + 6 * (unsigned)color.green | ||
91 | + (unsigned)color.blue) / 10; | ||
92 | } | ||
93 | |||
94 | /****************************************************************************** | ||
95 | * read_bmp_file() | ||
96 | * | ||
97 | * Reads a BMP file and puts the data in rockbox format in *data. | ||
98 | * | ||
99 | *****************************************************************************/ | ||
100 | int read_bmp_file(const char* filename, | ||
101 | unsigned char *bitmap, | ||
102 | int maxsize) | ||
103 | { | ||
104 | struct bmp_header bmph; | ||
105 | int fd, ret; | ||
106 | int width, height, depth; | ||
107 | int row, rowstart, rowstop, rowstep; | ||
108 | unsigned char invert; | ||
109 | unsigned char bmpbuf[4]; /* Buffer for one line */ | ||
110 | uint32_t palette[2]; | ||
111 | |||
112 | fd = open(filename, O_RDONLY); | ||
113 | |||
114 | /* Exit if file opening failed */ | ||
115 | if (fd < 0) | ||
116 | { | ||
117 | DEBUGF("read_bmp_file: can't open '%s', rc: %d\n", filename, fd); | ||
118 | return fd * 10 - 1; | ||
119 | } | ||
120 | |||
121 | /* read fileheader */ | ||
122 | ret = read(fd, &bmph, sizeof(struct bmp_header)); | ||
123 | if (ret < 0) | ||
124 | return ret * 10 - 2; | ||
125 | |||
126 | if (ret != sizeof(struct bmp_header)) { | ||
127 | DEBUGF("read_bmp_file: can't read BMP header."); | ||
128 | return -3; | ||
129 | } | ||
130 | |||
131 | width = readlong(&bmph.width); | ||
132 | if (width > 8) | ||
133 | { | ||
134 | DEBUGF("read_bmp_file: Bitmap too wide (%d pixels, max is 8)\n", width); | ||
135 | return -4; | ||
136 | } | ||
137 | |||
138 | depth = readshort(&bmph.bit_count); | ||
139 | if (depth != 1) | ||
140 | { | ||
141 | DEBUGF("read_bmp_fd: Wrong depth (%d, must be 1)\n", depth); | ||
142 | return -5; | ||
143 | } | ||
144 | |||
145 | height = readlong(&bmph.height); | ||
146 | if (height < 0) | ||
147 | { /* Top-down BMP file */ | ||
148 | height = -height; | ||
149 | rowstart = 0; | ||
150 | rowstop = height; | ||
151 | rowstep = 1; | ||
152 | } | ||
153 | else | ||
154 | { /* normal BMP */ | ||
155 | rowstart = height - 1; | ||
156 | rowstop = -1; | ||
157 | rowstep = -1; | ||
158 | } | ||
159 | |||
160 | /* Check if this fits the buffer */ | ||
161 | if (height > maxsize) | ||
162 | { | ||
163 | DEBUGF("read_bmp_fd: Bitmap too high for buffer: %d bytes.\n", height); | ||
164 | return -6; | ||
165 | } | ||
166 | |||
167 | if (read(fd, palette, 2 * sizeof(uint32_t)) | ||
168 | != 2 * (int)sizeof(uint32_t)) | ||
169 | { | ||
170 | DEBUGF("read_bmp_fd: Can't read color palette\n"); | ||
171 | return -7; | ||
172 | } | ||
173 | invert = (brightness((union rgb_union)palette[1]) | ||
174 | > brightness((union rgb_union)palette[0])) | ||
175 | ? 0xff : 0x00; | ||
176 | |||
177 | /* Search to the beginning of the image data */ | ||
178 | lseek(fd, (off_t)readlong(&bmph.off_bits), SEEK_SET); | ||
179 | memset(bitmap, 0, height); | ||
180 | |||
181 | /* loop to read rows and put them to buffer */ | ||
182 | for (row = rowstart; row != rowstop; row += rowstep) | ||
183 | { | ||
184 | /* read one row */ | ||
185 | ret = read(fd, bmpbuf, 4); | ||
186 | if (ret != 4) | ||
187 | { | ||
188 | DEBUGF("read_bmp_fd: error reading image, read returned: %d " | ||
189 | "expected: 4\n", ret); | ||
190 | return -9; | ||
191 | } | ||
192 | bitmap[row] = bmpbuf[0] ^ invert; | ||
193 | } | ||
194 | |||
195 | DEBUGF("totalsize: %d\n", totalsize); | ||
196 | |||
197 | close(fd); | ||
198 | return height; /* return the used buffer size. */ | ||
199 | } | ||