@@ -124,13 +124,74 @@ void AddHexBytes(FILE *f, void *pData, int iLen, int bLast)
124
124
fprintf (f , "};\n" );
125
125
}
126
126
} /* AddHexBytes() */
127
+ //
128
+ // The user passed a file with the wrong bit depth (not 1)
129
+ // convert to 1-bpp by converting each color to 0 or 1 based on the gray level
130
+ //
131
+ void ConvertTo1Bpp (uint8_t * pBMP , int w , int h , int iBpp , uint8_t * palette )
132
+ {
133
+ int g , x , y , iDelta , iPitch , iDestPitch ;
134
+ uint8_t * s , * d , * pPal , u8 , count ;
135
+
136
+ iPitch = (w * iBpp )/8 ;
137
+ iPitch = (iPitch + 3 ) & 0xfffc ;
138
+ iDestPitch = (w + 7 )/8 ;
139
+ iDestPitch = (iDestPitch + 3 ) & 0xfffc ; // round to nearest "DWORD"
140
+ iDelta = iBpp /8 ;
141
+ for (y = 0 ; y < h ; y ++ ) {
142
+ s = & pBMP [iPitch * y ];
143
+ d = & pBMP [iDestPitch * y ]; // overwrite the original data as we change it
144
+ count = 8 ; // bits in a byte
145
+ u8 = 0 ; // start with all black
146
+ for (x = 0 ; x < w ; x ++ ) { // slower code, but less code :)
147
+ u8 <<= 1 ;
148
+ switch (iBpp ) {
149
+ case 24 :
150
+ case 32 :
151
+ g = (s [0 ] + s [1 ]* 2 + s [2 ])/4 ; // gray value
152
+ s += iDelta ;
153
+ break ;
154
+ case 16 :
155
+ g = s [1 ] & 0xf8 ; // red
156
+ g += ((s [0 ] | s [1 ] << 8 ) << 2 ) & 0x1f0 ; // green x 2
157
+ g += (s [0 ] << 3 ) & 0xf8 ; // blue
158
+ g /= 4 ;
159
+ s += 2 ;
160
+ break ;
161
+ case 8 :
162
+ pPal = & palette [s [0 ] * 4 ];
163
+ g = (pPal [0 ] + pPal [1 ]* 2 + pPal [2 ])/4 ;
164
+ s ++ ;
165
+ break ;
166
+ case 4 :
167
+ if (x & 1 ) {
168
+ pPal = & palette [(s [0 ] & 0xf ) * 4 ];
169
+ g = (pPal [0 ] + pPal [1 ]* 2 + pPal [2 ])/4 ;
170
+ s ++ ;
171
+ } else {
172
+ pPal = & palette [(s [0 ]>>4 ) * 4 ];
173
+ g = (pPal [0 ] + pPal [1 ]* 2 + pPal [2 ])/4 ;
174
+ }
175
+ break ;
176
+ } // switch on bpp
177
+ if (g >= 128 ) u8 |= 1 ; // white
178
+ count -- ;
179
+ if (count == 0 ) { // byte is full, move on
180
+ * d ++ = u8 ;
181
+ u8 = 0 ;
182
+ count = 8 ;
183
+ }
184
+ } // for x
185
+ } // for y
186
+ } /* ConvertTo1Bpp() */
127
187
128
188
int main (int argc , const char * argv []) {
129
- uint8_t * pBMP , * pOut ;
189
+ uint8_t * s , * pBMP , * pOut ;
130
190
int rc , w , h , y , bpp ;
131
191
int iOutSize , iPitch ;
132
192
G5ENCIMAGE g5enc ;
133
193
BB_BITMAP bbbm ;
194
+ uint8_t palette [1024 ];
134
195
int bHFile ; // flag indicating if the output will be a .H file of hex data
135
196
136
197
printf ("Group5 image conversion tool\n" );
@@ -141,48 +202,48 @@ int main(int argc, const char * argv[]) {
141
202
pOut = (uint8_t * )argv [2 ] + strlen (argv [2 ]) - 1 ;
142
203
bHFile = (pOut [0 ] == 'H' || pOut [0 ] == 'h' ); // output an H file?
143
204
144
- pBMP = ReadBMP (argv [1 ], & w , & h , & bpp , NULL );
145
- if (bpp == 1 ) {
146
- uint8_t * s = pBMP ;
147
-
148
- printf ("bmp size %d x %d\n" , w , h );
149
- iPitch = (w + 7 ) >> 3 ;
150
- pOut = (uint8_t * )malloc (iPitch * h );
151
- rc = g5_encode_init (& g5enc , w , h , pOut , iPitch * h );
152
- for (y = 0 ; y < h && rc == G5_SUCCESS ; y ++ ) {
153
- rc = g5_encode_encodeLine (& g5enc , s );
154
- s += iPitch ;
155
- }
156
- if (rc == G5_ENCODE_COMPLETE ) {
157
- FILE * f ;
158
- printf ("Encode succeeded!\n" );
159
- iOutSize = g5_encode_getOutSize (& g5enc );
160
- printf ("Input size: %d bytes, output size: %d bytes\n" , iPitch * h , iOutSize );
161
- printf ("Compression ratio: %2.1f:1\n" , (float )(iPitch * h ) / (float )iOutSize );
162
- bbbm .u16Marker = BB_BITMAP_MARKER ;
163
- bbbm .width = w ;
164
- bbbm .height = h ;
165
- bbbm .size = iOutSize ;
166
- f = fopen (argv [2 ], "w+b" );
167
- if (!f ) {
168
- printf ("Error opening: %s\n" , argv [2 ]);
169
- } else {
170
- if (bHFile ) { // generate HEX file to include in a project
171
- StartHexFile (f , iOutSize + sizeof (BB_BITMAP ), w , h , argv [2 ]);
172
- AddHexBytes (f , & bbbm , sizeof (BB_BITMAP ), 0 );
173
- AddHexBytes (f , pOut , iOutSize , 1 );
174
- } else { // generate a binary file
175
- fwrite (& bbbm , 1 , sizeof (BB_BITMAP ), f );
176
- fwrite (pOut , 1 , iOutSize , f );
177
- }
178
- fflush (f );
179
- fclose (f );
180
- }
205
+ pBMP = ReadBMP (argv [1 ], & w , & h , & bpp , palette );
206
+ if (bpp != 1 ) { // need to convert it to 1-bpp
207
+ printf ("Converting from %d-bpp to 1-bpp\n" , bpp );
208
+ ConvertTo1Bpp (pBMP , w , h , bpp , palette );
209
+ }
210
+ s = pBMP ;
211
+ printf ("Bitmap size: %d x %d\n" , w , h );
212
+ iPitch = (w + 7 ) >> 3 ;
213
+ pOut = (uint8_t * )malloc (iPitch * h );
214
+ rc = g5_encode_init (& g5enc , w , h , pOut , iPitch * h );
215
+ for (y = 0 ; y < h && rc == G5_SUCCESS ; y ++ ) {
216
+ rc = g5_encode_encodeLine (& g5enc , s );
217
+ s += iPitch ;
218
+ }
219
+ if (rc == G5_ENCODE_COMPLETE ) {
220
+ FILE * f ;
221
+ iOutSize = g5_encode_getOutSize (& g5enc );
222
+ printf ("Input data size: %d bytes, compressed size: %d bytes\n" , iPitch * h , iOutSize );
223
+ printf ("Compression ratio: %2.1f:1\n" , (float )(iPitch * h ) / (float )iOutSize );
224
+ bbbm .u16Marker = BB_BITMAP_MARKER ;
225
+ bbbm .width = w ;
226
+ bbbm .height = h ;
227
+ bbbm .size = iOutSize ;
228
+ f = fopen (argv [2 ], "w+b" );
229
+ if (!f ) {
230
+ printf ("Error opening: %s\n" , argv [2 ]);
181
231
} else {
182
- printf ("Error encoding image: %d\n" , rc );
232
+ if (bHFile ) { // generate HEX file to include in a project
233
+ StartHexFile (f , iOutSize + sizeof (BB_BITMAP ), w , h , argv [2 ]);
234
+ AddHexBytes (f , & bbbm , sizeof (BB_BITMAP ), 0 );
235
+ AddHexBytes (f , pOut , iOutSize , 1 );
236
+ printf (".H file created successfully!\n" );
237
+ } else { // generate a binary file
238
+ fwrite (& bbbm , 1 , sizeof (BB_BITMAP ), f );
239
+ fwrite (pOut , 1 , iOutSize , f );
240
+ printf ("Binary file created successfully!\n" );
241
+ }
242
+ fflush (f );
243
+ fclose (f );
183
244
}
184
245
} else {
185
- printf ("Only 1-bpp images are supported. \n" );
246
+ printf ("Error encoding image: %d \n" , rc );
186
247
}
187
248
free (pBMP );
188
249
return 0 ;
0 commit comments