added image convert tool

This commit is contained in:
Laurence Bank
2024-09-30 09:05:01 +01:00
parent 680e5dc2d8
commit b3144ec2e5
8 changed files with 191 additions and 50 deletions
-1
View File
@@ -9,7 +9,6 @@
// work with the compressed font files created by the Group5 fontconvert tool
//
#include <Group5.h>
#include "bb_font.h"
#include <bb_spi_lcd.h>
#include "Roboto_Black_40.h" // BBF (BitBank Font file included as hex data to compile with the sketch)
-1
View File
@@ -21,7 +21,6 @@
#include FT_GLYPH_H
#include FT_MODULE_H
#include FT_TRUETYPE_DRIVER_H
#include "../src/bb_font.h" // BitBank font structures
#include "../src/g5enc.inl" // Group5 image compression library
G5ENCIMAGE g5enc; // Group5 encoder state
+11
View File
@@ -0,0 +1,11 @@
all: imgconvert
CC = gcc
CFLAGS = -Wall
imgconvert: main.c
$(CC) $(CFLAGS) $< -o $@
strip $@
clean:
rm -f imgconvert
+143
View File
@@ -0,0 +1,143 @@
//
//
// Group5 Image Compressor tool
// Written by Larry Bank
// Copyright (c) 2024 BitBank Software, Inc.
//
#include <stdio.h>
#include "../src/Group5.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() */
int main(int argc, const char * argv[]) {
uint8_t *pBMP, *pOut;
int rc, w, h, y, bpp;
int iOutSize, iPitch;
G5ENCIMAGE g5enc;
BB_BITMAP bbbm;
printf("Group5 image conversion tool\n");
if (argc != 3) {
printf("Usage: ./imgconvert <WinBMP 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(iPitch * h);
rc = g5_encode_init(&g5enc, w, h, pOut, iPitch * h);
for (y=0; y<h && rc == G5_SUCCESS; y++) {
rc = g5_encode_encodeLine(&g5enc, s);
s += iPitch;
}
if (rc == G5_ENCODE_COMPLETE) {
FILE *f;
printf("Encode succeeded!\n");
iOutSize = g5_encode_getOutSize(&g5enc);
printf("Input size = %d, output size = %d\n", iPitch*h, iOutSize);
bbbm.u16Marker = BB_BITMAP_MARKER;
bbbm.width = w;
bbbm.height = h;
bbbm.size = iOutSize;
f = fopen(argv[2], "w+b");
if (!f) {
printf("Error opening: %s\n", argv[2]);
} else {
fwrite(&bbbm, 1, sizeof(BB_BITMAP), f);
fwrite(pOut, 1, iOutSize, f);
fflush(f);
fclose(f);
}
} else {
printf("Error encoding image: %d\n", rc);
}
} else {
printf("Only 1-bpp images are supported.\n");
}
free(pBMP);
return 0;
} /* main() */
+35
View File
@@ -131,6 +131,41 @@ typedef struct g5_enc_image_tag
int16_t RefFlips[MAX_IMAGE_FLIPS];
} G5ENCIMAGE;
// 16-bit marker at the start of a BB_FONT file
// (BitBank FontFile)
#define BB_FONT_MARKER 0xBBFF
// 16-bit marker at the start of a BB_BITMAP file
// (BitBank BitmapFile)
#define BB_BITMAP_MARKER 0xBBBF
// Font info per character (glyph)
typedef struct {
uint16_t bitmapOffset; // Offset to compressed bitmap data for this glyph (starting from the end of the BB_GLYPH[] array)
uint8_t width; // bitmap width in pixels
uint8_t xAdvance; // total width in pixels (bitmap + padding)
uint16_t height; // bitmap height in pixels
int16_t xOffset; // left padding to upper left corner
int16_t yOffset; // padding from baseline to upper left corner (usually negative)
} BB_GLYPH;
// This structure is stored at the beginning of a BB_FONT file
typedef struct {
uint16_t u16Marker; // 16-bit Marker defining a BB_FONT file
uint16_t first; // first char (ASCII value)
uint16_t last; // last char (ASCII value)
uint16_t height; // total height of font
uint32_t rotation; // store this as 32-bits to not have a struct packing problem
BB_GLYPH glyphs[]; // Array of glyphs (one for each char)
} BB_FONT;
// This structure defines the start of a compressed bitmap file
typedef struct {
uint16_t u16Marker; // 16-bit marker defining a BB_BITMAP file
uint16_t width;
uint16_t height;
uint16_t size; // compressed data size (not including this 8-byte header)
} BB_BITMAP;
#ifdef __cplusplus
//
// The G5 classes wrap portable C code which does the actual work
+1 -1
View File
@@ -21,7 +21,7 @@
#define __BB_EP_GFX__
#include "Group5.h"
#include "g5dec.inl"
#include "bb_font.h"
static G5DECIMAGE g5dec;
// forward declarations
void InvertBytes(uint8_t *pData, uint8_t bLen);
+1 -1
View File
@@ -39,7 +39,7 @@ void delay(int);
#endif
#include "bb_ep.inl" // All of the display interface code is in here
#include "bb_ep_gfx.inl" // drawing code
#include "bb_font.h" // bitbank compressed font info
#ifdef __cplusplus
//
// C++ Class implementation
-46
View File
@@ -1,46 +0,0 @@
//
// C structures for defining a BB_FONT file
// Written by Larry Bank
// Copyright (c) 2024 BitBank Software, Inc.
//
// Use of this software is governed by the Business Source License
// included in the file ./LICENSE.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// ./APL.txt.
//
// The BB_FONT is at the start of the file
// followed by BB_GLYPH structures for each character
// and finally the packed bitmap data (one after another)
// is at the end of the file
//
#ifndef _BB_FONT_H_
#define _BB_FONT_H_
// 16-bit marker at the start of a BB_FONT file
// (BitBank FontFile)
#define BB_MARKER 0xBBFF
// Font info per character (glyph)
typedef struct {
uint16_t bitmapOffset; // Offset to compressed bitmap data for this glyph (starting from the end of the BB_GLYPH[] array)
uint8_t width; // bitmap width in pixels
uint8_t xAdvance; // total width in pixels (bitmap + padding)
uint16_t height; // bitmap height in pixels
int16_t xOffset; // left padding to upper left corner
int16_t yOffset; // padding from baseline to upper left corner (usually negative)
} BB_GLYPH;
// This structure is stored at the beginning of a BB_FONT file
typedef struct {
uint16_t u16Marker; // 16-bit Marker defining a BB_FONT file
uint16_t first; // first char (ASCII value)
uint16_t last; // last char (ASCII value)
uint16_t height; // total height of font
uint32_t rotation; // store this as 32-bits to not have a struct packing problem
BB_GLYPH glyphs[]; // Array of glyphs (one for each char)
} BB_FONT;
#endif // _BB_FONT_H_