mirror of
https://github.com/usetrmnl/bb_epaper.git
synced 2026-04-29 13:43:26 -07:00
138 lines
3.6 KiB
C
138 lines
3.6 KiB
C
//
|
|
// main.c
|
|
// Group5
|
|
//
|
|
// Created by Larry Bank on 8/19/24.
|
|
//
|
|
|
|
#include <stdio.h>
|
|
#include "../../../src/g5enc.inl"
|
|
//
|
|
// Read a Windows BMP file into memory
|
|
//
|
|
uint8_t * ReadBMP(const char *fname, int *width, int *height, int *bpp, unsigned char *pPal)
|
|
{
|
|
int y, w, h, bits, offset;
|
|
uint8_t *s, *d, *pTemp, *pBitmap;
|
|
int pitch, bytewidth;
|
|
int iSize, iDelta;
|
|
FILE *infile;
|
|
|
|
infile = fopen(fname, "r+b");
|
|
if (infile == NULL) {
|
|
printf("Error opening input file %s\n", fname);
|
|
return NULL;
|
|
}
|
|
// Read the bitmap into RAM
|
|
fseek(infile, 0, SEEK_END);
|
|
iSize = (int)ftell(infile);
|
|
fseek(infile, 0, SEEK_SET);
|
|
pBitmap = (uint8_t *)malloc(iSize);
|
|
pTemp = (uint8_t *)malloc(iSize);
|
|
fread(pTemp, 1, iSize, infile);
|
|
fclose(infile);
|
|
|
|
if (pTemp[0] != 'B' || pTemp[1] != 'M' || pTemp[14] < 0x28) {
|
|
free(pBitmap);
|
|
free(pTemp);
|
|
printf("Not a Windows BMP file!\n");
|
|
return NULL;
|
|
}
|
|
w = *(int32_t *)&pTemp[18];
|
|
h = *(int32_t *)&pTemp[22];
|
|
bits = *(int16_t *)&pTemp[26] * *(int16_t *)&pTemp[28];
|
|
if (bits <= 8 && pPal != NULL) { // it has a palette, copy it
|
|
uint8_t *p = pPal;
|
|
for (int i=0; i<(1<<bits); i++)
|
|
{
|
|
*p++ = pTemp[54+i*4];
|
|
*p++ = pTemp[55+i*4];
|
|
*p++ = pTemp[56+i*4];
|
|
}
|
|
}
|
|
offset = *(int32_t *)&pTemp[10]; // offset to bits
|
|
if (bits == 1) {
|
|
bytewidth = (w+7) >> 3;
|
|
} else {
|
|
bytewidth = (w * bits) >> 3;
|
|
}
|
|
pitch = (bytewidth + 3) & 0xfffc; // DWORD aligned
|
|
// move up the pixels
|
|
d = pBitmap;
|
|
s = &pTemp[offset];
|
|
iDelta = pitch;
|
|
if (h > 0) {
|
|
iDelta = -pitch;
|
|
s = &pTemp[offset + (h-1) * pitch];
|
|
} else {
|
|
h = -h;
|
|
}
|
|
for (y=0; y<h; y++) {
|
|
if (bits == 32) {// need to swap red and blue
|
|
for (int i=0; i<bytewidth; i+=4) {
|
|
d[i] = s[i+2];
|
|
d[i+1] = s[i+1];
|
|
d[i+2] = s[i];
|
|
d[i+3] = s[i+3];
|
|
}
|
|
} else {
|
|
memcpy(d, s, bytewidth);
|
|
}
|
|
d += bytewidth;
|
|
s += iDelta;
|
|
}
|
|
*width = w;
|
|
*height = h;
|
|
*bpp = bits;
|
|
free(pTemp);
|
|
return pBitmap;
|
|
|
|
} /* ReadBMP() */
|
|
|
|
#define OUTSIZE 65536
|
|
|
|
int main(int argc, const char * argv[]) {
|
|
uint8_t *pBMP, *pOut = NULL;
|
|
int rc, w, h, y, bpp;
|
|
int iOutSize, iPitch;
|
|
G5ENCIMAGE g5enc;
|
|
|
|
printf("G5 file compressor\n");
|
|
if (argc != 3) {
|
|
printf("Usage: ./Group5 <WinBMP 1-bpp image> <g5 compressed image>\n");
|
|
return -1;
|
|
}
|
|
pBMP = ReadBMP(argv[1], &w, &h, &bpp, NULL);
|
|
if (bpp == 1) {
|
|
uint8_t *s = pBMP;
|
|
|
|
printf("bmp size %d x %d\n", w, h);
|
|
iPitch = (w+7) >> 3;
|
|
pOut = (uint8_t *)malloc(OUTSIZE);
|
|
rc = g5_encode_init(&g5enc, w, h, pOut, OUTSIZE);
|
|
for (y=0; y<h && rc == G5_SUCCESS; y++) {
|
|
rc = g5_encode_encodeLine(&g5enc, s);
|
|
s += iPitch;
|
|
}
|
|
if (rc == G5_ENCODE_COMPLETE) {
|
|
FILE *fOut;
|
|
printf("Encode succeeded!\n");
|
|
iOutSize = g5_encode_getOutSize(&g5enc);
|
|
printf("Input size = %d, output size = %d\n", iPitch*h, iOutSize);
|
|
fOut = fopen(argv[2], "w+b");
|
|
if (fOut) {
|
|
fwrite(pOut, 1, iOutSize, fOut);
|
|
fflush(fOut);
|
|
fclose(fOut);
|
|
} else {
|
|
printf("Error opening output file: %s\n", argv[2]);
|
|
}
|
|
}
|
|
} else {
|
|
printf("Only 1-bpp images are supported.\n");
|
|
}
|
|
free(pBMP);
|
|
free(pOut);
|
|
return 0;
|
|
}
|