aqhome-tool: started working on code to convert BMP file to assembler data.
This commit is contained in:
@@ -51,6 +51,7 @@
|
|||||||
aqhome
|
aqhome
|
||||||
aqhtool_nodes
|
aqhtool_nodes
|
||||||
aqhtool_data
|
aqhtool_data
|
||||||
|
aqhtool_image
|
||||||
</useTargets>
|
</useTargets>
|
||||||
|
|
||||||
<libraries>
|
<libraries>
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
<subdirs>
|
<subdirs>
|
||||||
nodes
|
nodes
|
||||||
data
|
data
|
||||||
|
image
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
62
apps/aqhome-tool/image/0BUILD
Normal file
62
apps/aqhome-tool/image/0BUILD
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml?>
|
||||||
|
|
||||||
|
<gwbuild>
|
||||||
|
|
||||||
|
<target type="ConvenienceLibrary" name="aqhtool_image" >
|
||||||
|
|
||||||
|
<includes type="c" >
|
||||||
|
$(gwenhywfar_cflags)
|
||||||
|
-I$(topsrcdir)
|
||||||
|
-I$(topbuilddir)
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
<includes type="tm2" >
|
||||||
|
--include=$(builddir)
|
||||||
|
--include=$(srcdir)
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
||||||
|
|
||||||
|
<setVar name="tm2flags" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/typefiles" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_sources" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_pub">
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_priv" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<headers dist="true" >
|
||||||
|
readbmp.h
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
<sources>
|
||||||
|
$(local/typefiles)
|
||||||
|
|
||||||
|
readbmp.c
|
||||||
|
</sources>
|
||||||
|
|
||||||
|
<useTargets>
|
||||||
|
</useTargets>
|
||||||
|
|
||||||
|
<libraries>
|
||||||
|
</libraries>
|
||||||
|
|
||||||
|
<subdirs>
|
||||||
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
|
<extradist>
|
||||||
|
</extradist>
|
||||||
|
|
||||||
|
|
||||||
|
</target>
|
||||||
|
|
||||||
|
|
||||||
|
</gwbuild>
|
||||||
457
apps/aqhome-tool/image/readbmp.c
Normal file
457
apps/aqhome-tool/image/readbmp.c
Normal file
@@ -0,0 +1,457 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "./readbmp.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/i18n.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/text.h>
|
||||||
|
#include <gwenhywfar/args.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* defs
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define I18S(msg) msg
|
||||||
|
#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg)
|
||||||
|
|
||||||
|
#define A_ARG GWEN_ARGS_FLAGS_HAS_ARGUMENT
|
||||||
|
#define A_END (GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST)
|
||||||
|
#define A_CHAR GWEN_ArgsType_Char
|
||||||
|
#define A_INT GWEN_ArgsType_Int
|
||||||
|
|
||||||
|
|
||||||
|
#define BMP_FILE_OFFS_FILEHEADER 0
|
||||||
|
#define BMP_FILE_OFFS_IMAGEHEADER 14
|
||||||
|
|
||||||
|
#define BMP_FILEHEADER_OFFS_TYPE 0 /* 2 bytes ("BM") */
|
||||||
|
#define BMP_FILEHEADER_OFFS_FSIZE 2 /* 4 bytes */
|
||||||
|
#define BMP_FILEHEADER_OFFS_RESERVED1 6 /* 2 bytes */
|
||||||
|
#define BMP_FILEHEADER_OFFS_RESERVED2 8 /* 2 bytes */
|
||||||
|
#define BMP_FILEHEADER_OFFS_PIXELOFFS 10 /* 4 bytes offset to begin of pixel data */
|
||||||
|
#define BMP_FILEHEADER_SIZE 14
|
||||||
|
|
||||||
|
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_HSIZE 0 /* 4 bytes header size */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_WIDTH 4 /* 4 bytes */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_HEIGHT 8 /* 4 bytes */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_PLANES 12 /* 2 bytes (1) */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_BPP 14 /* 2 bytes bit per pixel */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_COMPR 16 /* 4 bytes (0=uncompressed) */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_IMGSIZE 20 /* 4 bytes (may be 0 for uncompressed data) */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_XPPM 24 /* 4 bytes X pixel per meter */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_YPPM 28 /* 4 bytes Y pixel per meter */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_COLORMAPENTRIES 32 /* 4 bytes number of color map entries actually used */
|
||||||
|
#define BMP_IMAGEHEADER_OFFS_IMPORTANT 36 /* 4 bytes number of significant colors */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int AQH_Tool_ReadAndDumpBmpFile(const char *fname);
|
||||||
|
static int AQH_Tool_ExportBmpFile(const char *fname);
|
||||||
|
|
||||||
|
static int _exportBmp_1bpp(const BMP_FILE *bf);
|
||||||
|
|
||||||
|
static BMP_FILEHEADER *_fileHeader_new();
|
||||||
|
static void _fileHeader_free(BMP_FILEHEADER *fh);
|
||||||
|
|
||||||
|
static BMP_IMAGEHEADER *_imageHeader_new();
|
||||||
|
static void _imageHeader_free(BMP_IMAGEHEADER *ih);
|
||||||
|
|
||||||
|
static void _dumpBmpFileHeader(const BMP_FILEHEADER *fh);
|
||||||
|
static void _dumpBmpImageHeader(const BMP_IMAGEHEADER *ih);
|
||||||
|
static BMP_FILEHEADER *_readFileHeaderAt(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset);
|
||||||
|
static BMP_IMAGEHEADER *_readImageHeaderAt(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset);
|
||||||
|
|
||||||
|
static uint16_t _readUint16At(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset, uint16_t defaultValue);
|
||||||
|
static uint32_t _readUint32At(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset, uint32_t defaultValue);
|
||||||
|
static int32_t _readInt32At(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset, int32_t defaultValue);
|
||||||
|
|
||||||
|
static GWEN_BUFFER *_readFileIntoBuffer(const char *fname);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* code
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_Tool_DumpBmpFile(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
|
||||||
|
{
|
||||||
|
GWEN_DB_NODE *dbLocalArgs;
|
||||||
|
int rv;
|
||||||
|
const char *sFilename;
|
||||||
|
const GWEN_ARGS args[]= {
|
||||||
|
/* flags type name min max s long short_descr, long_descr */
|
||||||
|
{ A_ARG, A_CHAR, "bmpFile", 1, 1, "i", "bmpFile", I18S("BMP file to read"), NULL},
|
||||||
|
{ A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
dbLocalArgs=GWEN_DB_GetGroup(dbGlobalArgs, GWEN_DB_FLAGS_DEFAULT, "local");
|
||||||
|
rv=GWEN_Args_Check(argc, argv, 1, GWEN_ARGS_MODE_ALLOW_FREEPARAM, args, dbLocalArgs);
|
||||||
|
if (rv==GWEN_ARGS_RESULT_ERROR) {
|
||||||
|
fprintf(stderr, "ERROR: Could not parse arguments\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (rv==GWEN_ARGS_RESULT_HELP) {
|
||||||
|
GWEN_BUFFER *ubuf;
|
||||||
|
|
||||||
|
ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
|
||||||
|
if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
|
||||||
|
fprintf(stderr, "ERROR: Could not create help string\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
|
||||||
|
GWEN_Buffer_free(ubuf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sFilename=GWEN_DB_GetCharValue(dbLocalArgs, "bmpFile", 0, NULL);
|
||||||
|
if (!(sFilename && *sFilename)) {
|
||||||
|
fprintf(stderr, "Missing file name\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//return AQH_Tool_ReadAndDumpBmpFile(sFilename);
|
||||||
|
return AQH_Tool_ExportBmpFile(sFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_Tool_ReadAndDumpBmpFile(const char *fname)
|
||||||
|
{
|
||||||
|
BMP_FILE *bf;
|
||||||
|
|
||||||
|
bf=BMP_File_fromFile(fname);
|
||||||
|
if (bf) {
|
||||||
|
_dumpBmpFileHeader(bf->fileHeader);
|
||||||
|
_dumpBmpImageHeader(bf->imageHeader);
|
||||||
|
BMP_File_free(bf);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_Tool_ExportBmpFile(const char *fname)
|
||||||
|
{
|
||||||
|
BMP_FILE *bf;
|
||||||
|
|
||||||
|
bf=BMP_File_fromFile(fname);
|
||||||
|
if (bf) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
_dumpBmpFileHeader(bf->fileHeader);
|
||||||
|
_dumpBmpImageHeader(bf->imageHeader);
|
||||||
|
if (bf->imageHeader->bitsPerPixel==1)
|
||||||
|
rv=_exportBmp_1bpp(bf);
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Invalid bits per pixel (%d)", bf->imageHeader->bitsPerPixel);
|
||||||
|
rv=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMP_File_free(bf);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 2;;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _exportBmp_1bpp(const BMP_FILE *bf)
|
||||||
|
{
|
||||||
|
const uint8_t *ptrBuffer;
|
||||||
|
uint32_t lenBuffer;
|
||||||
|
uint32_t offsPixels;
|
||||||
|
const uint8_t *ptrPixels;
|
||||||
|
int imageWidth;
|
||||||
|
int imageHeight;
|
||||||
|
int rowWidthInBytes;
|
||||||
|
int columns;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
ptrBuffer=(const uint8_t *) GWEN_Buffer_GetStart(bf->buffer);
|
||||||
|
lenBuffer=GWEN_Buffer_GetUsedBytes(bf->buffer);
|
||||||
|
offsPixels=bf->fileHeader->offsPixels;
|
||||||
|
ptrPixels=ptrBuffer+offsPixels;
|
||||||
|
imageWidth=bf->imageHeader->imgWidth;
|
||||||
|
imageHeight=bf->imageHeader->imgHeight;
|
||||||
|
columns=imageWidth/8;
|
||||||
|
rowWidthInBytes=4*((columns+3)/4); /* BMPs have multiple of 4 bytes per row! */
|
||||||
|
fprintf(stdout, "imgData: \n");
|
||||||
|
fprintf(stdout, " .dw %d, %d\n", imageWidth, imageHeight);
|
||||||
|
|
||||||
|
for (y=imageHeight-1; y>=0; y--) {
|
||||||
|
const uint8_t *rowPtr;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
fprintf(stdout, " .db ");
|
||||||
|
rowPtr=ptrPixels+(y*rowWidthInBytes);
|
||||||
|
for (x=0; x<columns; x++) {
|
||||||
|
if (x)
|
||||||
|
fprintf(stdout, ", ");
|
||||||
|
fprintf(stdout, "0x%02x", rowPtr[x]^0xff);
|
||||||
|
}
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BMP_FILE *BMP_File_new(const char *fname)
|
||||||
|
{
|
||||||
|
BMP_FILE *bf;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(BMP_FILE, bf);
|
||||||
|
bf->filename=fname?strdup(fname):NULL;
|
||||||
|
return bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void BMP_File_free(BMP_FILE *bf)
|
||||||
|
{
|
||||||
|
if (bf) {
|
||||||
|
free(bf->filename);
|
||||||
|
_imageHeader_free(bf->imageHeader);
|
||||||
|
_fileHeader_free(bf->fileHeader);
|
||||||
|
GWEN_Buffer_free(bf->buffer);
|
||||||
|
GWEN_FREE_OBJECT(bf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BMP_FILE *BMP_File_fromFile(const char *fname)
|
||||||
|
{
|
||||||
|
BMP_FILE *bf;
|
||||||
|
const uint8_t *ptrBuffer;
|
||||||
|
uint32_t lenBuffer;
|
||||||
|
|
||||||
|
bf=BMP_File_new(fname);
|
||||||
|
bf->buffer=_readFileIntoBuffer(fname);
|
||||||
|
if (bf->buffer==NULL) {
|
||||||
|
fprintf(stderr, "Error reading bmp file \"%s\"\n", fname);
|
||||||
|
BMP_File_free(bf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ptrBuffer=(const uint8_t *) GWEN_Buffer_GetStart(bf->buffer);
|
||||||
|
lenBuffer=GWEN_Buffer_GetUsedBytes(bf->buffer);
|
||||||
|
|
||||||
|
bf->fileHeader=_readFileHeaderAt(ptrBuffer, lenBuffer, 0);
|
||||||
|
if (bf->fileHeader==NULL) {
|
||||||
|
fprintf(stderr, "Error reading bmp file header from \"%s\"\n", fname);
|
||||||
|
BMP_File_free(bf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bf->imageHeader=_readImageHeaderAt(ptrBuffer, lenBuffer, BMP_FILE_OFFS_IMAGEHEADER);
|
||||||
|
if (bf->imageHeader==NULL) {
|
||||||
|
fprintf(stderr, "Error reading bmp image header from \"%s\"\n", fname);
|
||||||
|
BMP_File_free(bf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BMP_FILEHEADER *_fileHeader_new()
|
||||||
|
{
|
||||||
|
BMP_FILEHEADER *fh;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(BMP_FILEHEADER, fh);
|
||||||
|
return fh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _fileHeader_free(BMP_FILEHEADER *fh)
|
||||||
|
{
|
||||||
|
if (fh) {
|
||||||
|
GWEN_FREE_OBJECT(fh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BMP_IMAGEHEADER *_imageHeader_new()
|
||||||
|
{
|
||||||
|
BMP_IMAGEHEADER *ih;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(BMP_IMAGEHEADER, ih);
|
||||||
|
return ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _imageHeader_free(BMP_IMAGEHEADER *ih)
|
||||||
|
{
|
||||||
|
if (ih) {
|
||||||
|
GWEN_FREE_OBJECT(ih);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _dumpBmpFileHeader(const BMP_FILEHEADER *fh)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "BMP File Header:\n");
|
||||||
|
fprintf(stderr, "- file type: %d\n", fh->fileType);
|
||||||
|
fprintf(stderr, "- file size: %d\n", fh->fileSize);
|
||||||
|
fprintf(stderr, "- Pixels at: %08x\n", fh->offsPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _dumpBmpImageHeader(const BMP_IMAGEHEADER *ih)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "BMP Image Header:\n");
|
||||||
|
fprintf(stderr, "- dims : %d x %d (%d planes, %d bpp)\n", ih->imgWidth, ih->imgHeight, ih->imgPlanes, ih->bitsPerPixel);
|
||||||
|
fprintf(stderr, "- compression : %d\n", ih->compression);
|
||||||
|
fprintf(stderr, "- image size : %d\n", ih->imgSize);
|
||||||
|
fprintf(stderr, "- resolution : %d x %d per meter\n", ih->imgXPixelsPerMeter, ih->imgYPixelsPerMeter);
|
||||||
|
fprintf(stderr, "- used colormap: %d entries (%d important)\n", ih->colorMapUsedEntries, ih->colorMapImportantColors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BMP_FILEHEADER *_readFileHeaderAt(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset)
|
||||||
|
{
|
||||||
|
BMP_FILEHEADER *fh;
|
||||||
|
|
||||||
|
if (lenBuffer<(offset+BMP_FILEHEADER_SIZE)) {
|
||||||
|
DBG_ERROR(NULL, "Offset 0x%08x out of boundary", offset);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fh=_fileHeader_new();
|
||||||
|
fh->fileType=_readUint16At(ptrBuffer, lenBuffer, offset+BMP_FILEHEADER_OFFS_TYPE, 0);
|
||||||
|
fh->fileSize=_readUint32At(ptrBuffer, lenBuffer, offset+BMP_FILEHEADER_OFFS_FSIZE, 0);
|
||||||
|
fh->offsPixels=_readUint32At(ptrBuffer, lenBuffer, offset+BMP_FILEHEADER_OFFS_PIXELOFFS, 0xffffffff);
|
||||||
|
|
||||||
|
return fh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BMP_IMAGEHEADER *_readImageHeaderAt(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset)
|
||||||
|
{
|
||||||
|
BMP_IMAGEHEADER *ih;
|
||||||
|
uint32_t hsize;
|
||||||
|
|
||||||
|
hsize=_readUint32At(ptrBuffer, lenBuffer, BMP_FILE_OFFS_IMAGEHEADER, 0xffffffff);
|
||||||
|
if (lenBuffer<(offset+hsize)) {
|
||||||
|
DBG_ERROR(NULL, "Offset 0x%08x out of boundary", offset);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ih=_imageHeader_new();
|
||||||
|
ih->imgWidth=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_WIDTH, 0);
|
||||||
|
ih->imgHeight=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_HEIGHT, 0);
|
||||||
|
ih->imgPlanes=_readUint16At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_PLANES, 0);
|
||||||
|
ih->bitsPerPixel=_readUint16At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_BPP, 0);
|
||||||
|
ih->compression=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_COMPR, 0);
|
||||||
|
ih->imgSize=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_IMGSIZE, 0);
|
||||||
|
ih->imgXPixelsPerMeter=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_XPPM, 0);
|
||||||
|
ih->imgYPixelsPerMeter=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_YPPM, 0);
|
||||||
|
ih->colorMapUsedEntries=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_COLORMAPENTRIES, 0);
|
||||||
|
ih->colorMapImportantColors=_readInt32At(ptrBuffer, lenBuffer, offset+BMP_IMAGEHEADER_OFFS_IMPORTANT, 0);
|
||||||
|
|
||||||
|
return ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t _readUint16At(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset, uint16_t defaultValue)
|
||||||
|
{
|
||||||
|
uint16_t v;
|
||||||
|
|
||||||
|
if (lenBuffer<(offset+2)) {
|
||||||
|
DBG_ERROR(NULL, "Offset 0x%08x out of boundary", offset);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
v=ptrBuffer[offset]+(ptrBuffer[offset+1]<<8);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t _readUint32At(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset, uint32_t defaultValue)
|
||||||
|
{
|
||||||
|
uint32_t v;
|
||||||
|
|
||||||
|
if (lenBuffer<(offset+4)) {
|
||||||
|
DBG_ERROR(NULL, "Offset 0x%08x out of boundary", offset);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
v=ptrBuffer[offset]+(ptrBuffer[offset+1]<<8)+(ptrBuffer[offset+2]<<16)+(ptrBuffer[offset+2]<<16);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int32_t _readInt32At(const uint8_t *ptrBuffer, uint32_t lenBuffer, uint32_t offset, int32_t defaultValue)
|
||||||
|
{
|
||||||
|
uint32_t v;
|
||||||
|
|
||||||
|
if (lenBuffer<(offset+4)) {
|
||||||
|
DBG_ERROR(NULL, "Offset 0x%08x out of boundary", offset);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
v=ptrBuffer[offset]+(ptrBuffer[offset+1]<<8)+(ptrBuffer[offset+2]<<16)+(ptrBuffer[offset+2]<<16);
|
||||||
|
return (int32_t) v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_BUFFER *_readFileIntoBuffer(const char *fname)
|
||||||
|
{
|
||||||
|
GWEN_BUFFER *buf;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
buf=GWEN_Buffer_new(0, 1024, 0, 1);
|
||||||
|
rv=GWEN_SyncIo_Helper_ReadFile(fname, buf);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "Error reading file \"%s\": %d", fname?fname:"<empty>", rv);
|
||||||
|
GWEN_Buffer_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
69
apps/aqhome-tool/image/readbmp.h
Normal file
69
apps/aqhome-tool/image/readbmp.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQHOME_TOOL_READBMP_H
|
||||||
|
#define AQHOME_TOOL_READBMP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <gwenhywfar/db.h>
|
||||||
|
#include <gwenhywfar/endpoint.h>
|
||||||
|
|
||||||
|
#include <aqhome/data/value.h>
|
||||||
|
#include <aqhome/data/device.h>
|
||||||
|
|
||||||
|
#include <aqhome/events2/eventloop.h>
|
||||||
|
#include <aqhome/events2/object.h>
|
||||||
|
#include <aqhome/ipc2/message.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BMP_FILEHEADER BMP_FILEHEADER;
|
||||||
|
struct BMP_FILEHEADER {
|
||||||
|
uint16_t fileType;
|
||||||
|
uint32_t fileSize;
|
||||||
|
uint32_t offsPixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BMP_IMAGEHEADER BMP_IMAGEHEADER;
|
||||||
|
struct BMP_IMAGEHEADER {
|
||||||
|
int32_t imgWidth;
|
||||||
|
int32_t imgHeight;
|
||||||
|
uint16_t imgPlanes; /* 1 */
|
||||||
|
uint16_t bitsPerPixel;
|
||||||
|
uint32_t compression;
|
||||||
|
uint32_t imgSize;
|
||||||
|
uint32_t imgXPixelsPerMeter;
|
||||||
|
uint32_t imgYPixelsPerMeter;
|
||||||
|
uint32_t colorMapUsedEntries;
|
||||||
|
uint32_t colorMapImportantColors;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BMP_FILE BMP_FILE;
|
||||||
|
struct BMP_FILE {
|
||||||
|
char *filename;
|
||||||
|
BMP_FILEHEADER *fileHeader;
|
||||||
|
BMP_IMAGEHEADER *imageHeader;
|
||||||
|
|
||||||
|
GWEN_BUFFER *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_Tool_DumpBmpFile(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv);
|
||||||
|
|
||||||
|
|
||||||
|
BMP_FILE *BMP_File_new(const char *fname);
|
||||||
|
void BMP_File_free(BMP_FILE *bf);
|
||||||
|
BMP_FILE *BMP_File_fromFile(const char *fname);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "./data/watch.h"
|
#include "./data/watch.h"
|
||||||
#include "./data/devicestate.h"
|
#include "./data/devicestate.h"
|
||||||
#include "./data/imgperioddata.h"
|
#include "./data/imgperioddata.h"
|
||||||
|
#include "./image/readbmp.h"
|
||||||
|
|
||||||
#include <aqhome/api.h>
|
#include <aqhome/api.h>
|
||||||
#include <aqhome/aqhome.h>
|
#include <aqhome/aqhome.h>
|
||||||
@@ -105,6 +106,7 @@ int main(int argc, char **argv)
|
|||||||
GWEN_FE_DAH("watch", AQH_Tool_Watch, I18N("Watch and print changes of values on the data server")),
|
GWEN_FE_DAH("watch", AQH_Tool_Watch, I18N("Watch and print changes of values on the data server")),
|
||||||
GWEN_FE_DAH("devicestate", AQH_Tool_DeviceState, I18N("Show state of devices")),
|
GWEN_FE_DAH("devicestate", AQH_Tool_DeviceState, I18N("Show state of devices")),
|
||||||
GWEN_FE_DAH("imgperioddata", AQH_Tool_ImgPeriodData, I18N("Create diagram of datapoints from a date range")),
|
GWEN_FE_DAH("imgperioddata", AQH_Tool_ImgPeriodData, I18N("Create diagram of datapoints from a date range")),
|
||||||
|
GWEN_FE_DAH("dumpbmp", AQH_Tool_DumpBmpFile, I18N("Dump headers of BMP file")),
|
||||||
GWEN_FE_END(),
|
GWEN_FE_END(),
|
||||||
};
|
};
|
||||||
const GWEN_FUNCS *func;
|
const GWEN_FUNCS *func;
|
||||||
|
|||||||
Reference in New Issue
Block a user