Skip to content

Commit 129dd17

Browse files
Laurence BankLaurence Bank
Laurence Bank
authored and
Laurence Bank
committed
Enhanced image convert tool to accept all bit depths as input
1 parent 3362800 commit 129dd17

File tree

1 file changed

+101
-40
lines changed

1 file changed

+101
-40
lines changed

imageconvert/main.c

Lines changed: 101 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,74 @@ void AddHexBytes(FILE *f, void *pData, int iLen, int bLast)
124124
fprintf(f, "};\n");
125125
}
126126
} /* 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() */
127187

128188
int main(int argc, const char * argv[]) {
129-
uint8_t *pBMP, *pOut;
189+
uint8_t *s, *pBMP, *pOut;
130190
int rc, w, h, y, bpp;
131191
int iOutSize, iPitch;
132192
G5ENCIMAGE g5enc;
133193
BB_BITMAP bbbm;
194+
uint8_t palette[1024];
134195
int bHFile; // flag indicating if the output will be a .H file of hex data
135196

136197
printf("Group5 image conversion tool\n");
@@ -141,48 +202,48 @@ int main(int argc, const char * argv[]) {
141202
pOut = (uint8_t *)argv[2] + strlen(argv[2]) - 1;
142203
bHFile = (pOut[0] == 'H' || pOut[0] == 'h'); // output an H file?
143204

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]);
181231
} 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);
183244
}
184245
} else {
185-
printf("Only 1-bpp images are supported.\n");
246+
printf("Error encoding image: %d\n", rc);
186247
}
187248
free(pBMP);
188249
return 0;

0 commit comments

Comments
 (0)