1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
#ifndef SRF_H_INCLUDED
#define SRF_H_INCLUDED
/*
* Structures for working with SRF (Garmin vehicle) files
* http://www.techmods.net/nuvi/
*
* Written by Mike Frysinger <vapier@gentoo.org>
* Released into the public domain
*/
#include "pm_config.h"
#include "pam.h"
struct srf_pstring {
uint32_t len;
char * val;
};
#define SRF_NUM_FRAMES 36
/*
File Header
16 bytes - string - "GARMIN BITMAP 01"
32 bytes - two 32-bit ints, [4, 4] -- purpose unknown
4 bytes - 32-bit int -- number of images (usually just 2)
4 bytes - 32-bit int, [5] -- purpose unknown
7 bytes - PString - "578"
4 bytes - 32-bit int, [6] -- purpose unknown
8 bytes - PString - version number ("1.00", "2.00", "2.10", or "2.20")
4 bytes - 32-bit int, [7] -- purpose unknown
16 bytes - PString - "006-D0578-XX" (where "XX" changes) --
I assume this is Garmin's product code?
*/
#define SRF_MAGIC "GARMIN BITMAP 01"
struct srf_header {
char magic[16 + 1];
uint32_t _int4[2];
uint32_t img_cnt;
uint32_t _int5;
struct srf_pstring s578;
uint32_t _int6;
struct srf_pstring ver;
uint32_t _int7;
struct srf_pstring prod;
};
/*
Image Header
12 bytes - three 32-bit ints, [0,16,0] -- purpose unknown
2 bytes - 16-bit int -- height of image (just the 3D section, so it's 80)
2 bytes - 16-bit int -- width of image (just the 3D section, 2880 or 2881)
2 bytes - [16, 8] -- purpose unknown
2 bytes - 16-bit int -- byte length of each line of image RGB data
(16-bit RGB), so "width * 2"
4 bytes - all zeroes -- purpose unknown
*/
struct srf_img_header {
uint32_t _ints[3];
uint16_t height, width;
char _bytes[2];
uint16_t line_len;
uint32_t zeros;
};
/*
Image Alpha Mask
4 bytes - 32-bit int, [11] -- Might specify the type of data that
follows?
4 bytes - 32-bit int, length of following data (width*height of 3D
section)
width*height bytes - alpha mask data, 0 = opaque, 128 = transparent
(across, then down)
Notes: The Garmin format has 129 values: [0..128] [opaque..transparent]
The PNG format has 256 values: [0..255] [transparent..opaque]
So we have to do a little edge case tweaking to keep things lossless.
*/
#define SRF_ALPHA_OPAQUE 0
#define SRF_ALPHA_TRANS 128
struct srf_img_alpha {
uint32_t type;
uint32_t data_len;
unsigned char * data;
};
/*
Image RGB Data
4 bytes - 32-bit int, [1] -- Might specify the type of data that follows?
4 bytes - 32-bit int, length of following data (width*height*2 of 3D
section, as the RGB data is 16-bit)
width*height*2 bytes - RBG values as "rrrrrggggg0bbbbb" bits
(across, then down)
*/
struct srf_img_data {
uint32_t type;
uint32_t data_len;
uint16_t * data;
};
struct srf_img {
struct srf_img_header header;
struct srf_img_alpha alpha;
struct srf_img_data data;
};
/*
Footer
arbitrary number of bytes - all 0xFF -- these are used (as well as the
checksum byte) to pad the file
size to a multiple of 256.
1 byte - checksum byte -- use this byte to adjust so that the ascii sum
of all bytes in the file is a multiple of 256.
*/
struct srf {
struct srf_header header;
struct srf_img * imgs;
};
uint8_t
srf_alpha_srftopam(uint8_t const d);
uint8_t
srf_alpha_pamtosrf(uint8_t const d);
void
srf_read(FILE * const ifP,
bool const verbose,
struct srf * const srfP);
void
srf_write(FILE * const ofP,
struct srf * const srfP);
void
srf_term(struct srf * const srfP);
void
srf_init(struct srf * const srfP);
void
srf_create_img(struct srf * const srfP,
uint16_t const width,
uint16_t const height);
#endif
|