diff --git a/apps/aqhome-tool/image/readbmp.c b/apps/aqhome-tool/image/readbmp.c index 71cc656..60854bd 100644 --- a/apps/aqhome-tool/image/readbmp.c +++ b/apps/aqhome-tool/image/readbmp.c @@ -69,6 +69,12 @@ static int AQH_Tool_ExportBmpFile(const char *fname); static int _exportBmp_1bpp(const BMP_FILE *bf); static int _exportBmp_gray8bpp(const BMP_FILE *bf); +static GWEN_BUFFER *_extractPixels_gray8bpp(const uint8_t *ptrPixels, int imageWidth, int imageHeight); +static void _printBytes_ASM(const char *sName, const uint8_t *ptrPixels, int lenPixels, int imageWidth, int imageHeight); +static GWEN_BUFFER *_rleEncode(const uint8_t *ptrPixels, int lenPixels); +static int _countRepeats(const uint8_t *ptrPixels, int lenPixels); + + static BMP_FILEHEADER *_fileHeader_new(); static void _fileHeader_free(BMP_FILEHEADER *fh); @@ -185,7 +191,6 @@ int AQH_Tool_ExportBmpFile(const char *fname) int _exportBmp_1bpp(const BMP_FILE *bf) { const uint8_t *ptrBuffer; - uint32_t lenBuffer; uint32_t offsPixels; const uint8_t *ptrPixels; int imageWidth; @@ -195,7 +200,6 @@ int _exportBmp_1bpp(const BMP_FILE *bf) 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; @@ -226,34 +230,51 @@ int _exportBmp_1bpp(const BMP_FILE *bf) int _exportBmp_gray8bpp(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; + GWEN_BUFFER *pixelBuf; + GWEN_BUFFER *asmBuf; 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; + + pixelBuf=_extractPixels_gray8bpp(ptrPixels, imageWidth, imageHeight); + asmBuf=_rleEncode((const uint8_t*) GWEN_Buffer_GetStart(pixelBuf), GWEN_Buffer_GetUsedBytes(pixelBuf)); + _printBytes_ASM("imageData", + (const uint8_t*) GWEN_Buffer_GetStart(asmBuf), GWEN_Buffer_GetUsedBytes(asmBuf), + imageWidth, imageHeight); + + fprintf(stderr, "Compression: %d -> %d bytes\n", GWEN_Buffer_GetUsedBytes(pixelBuf), GWEN_Buffer_GetUsedBytes(asmBuf)); + GWEN_Buffer_free(asmBuf); + GWEN_Buffer_free(pixelBuf); + + return 0; +} + + + +GWEN_BUFFER *_extractPixels_gray8bpp(const uint8_t *ptrPixels, int imageWidth, int imageHeight) +{ + int rowWidthInBytes; + int columns; + int y; + GWEN_BUFFER *destBuf; + + destBuf=GWEN_Buffer_new(0, 256, 0, 1); columns=imageWidth; 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; uint8_t currentByte=0; - int writtenBytes=0; int packedPixels=0; - fprintf(stdout, " .db "); rowPtr=ptrPixels+(y*rowWidthInBytes); for (x=0; x0) { + int countRepeats; + + countRepeats=_countRepeats(ptrPixels, lenPixels); + if (countRepeats<4) { + GWEN_Buffer_AppendByte(currentBuf, *ptrPixels); + numCurrentBuf=GWEN_Buffer_GetUsedBytes(currentBuf); + if (numCurrentBuf==127) { + GWEN_Buffer_AppendByte(resultBuf, numCurrentBuf); /* bit 7 =0 */ + GWEN_Buffer_AppendBytes(resultBuf, GWEN_Buffer_GetStart(currentBuf), numCurrentBuf); + GWEN_Buffer_Reset(currentBuf); + } + ptrPixels++; + lenPixels--; + } + else { + numCurrentBuf=GWEN_Buffer_GetUsedBytes(currentBuf); + if (numCurrentBuf>0) { + GWEN_Buffer_AppendByte(resultBuf, numCurrentBuf); /* bit 7 =0 */ + GWEN_Buffer_AppendBytes(resultBuf, GWEN_Buffer_GetStart(currentBuf), numCurrentBuf); + GWEN_Buffer_Reset(currentBuf); + } + GWEN_Buffer_AppendByte(resultBuf, countRepeats | 128); + GWEN_Buffer_AppendByte(resultBuf, *ptrPixels); + ptrPixels+=countRepeats; + lenPixels-=countRepeats; + } + } + + numCurrentBuf=GWEN_Buffer_GetUsedBytes(currentBuf); + if (numCurrentBuf>0) { + GWEN_Buffer_AppendByte(resultBuf, numCurrentBuf); /* bit 7 =0 */ + GWEN_Buffer_AppendBytes(resultBuf, GWEN_Buffer_GetStart(currentBuf), numCurrentBuf); + } + GWEN_Buffer_free(currentBuf); + + if (GWEN_Buffer_GetUsedBytes(resultBuf)==0) { + GWEN_Buffer_free(resultBuf); + return NULL; + } + + return resultBuf; +} + + + +int _countRepeats(const uint8_t *ptrPixels, int lenPixels) +{ + if (ptrPixels && lenPixels) { + int currentByte; + int count=1; + + currentByte=*(ptrPixels++); + lenPixels--; + while(ptrPixels && lenPixels) { + if (*ptrPixels==currentByte) { + count++; + if (count==127) + return count; + } + else + return count; + + ptrPixels++; + lenPixels--; + } + return count; } return 0; } @@ -288,6 +416,7 @@ int _exportBmp_gray8bpp(const BMP_FILE *bf) + BMP_FILE *BMP_File_new(const char *fname) { BMP_FILE *bf;