write images in IDX2RLE format.
This commit is contained in:
@@ -69,6 +69,12 @@ static int AQH_Tool_ExportBmpFile(const char *fname);
|
|||||||
static int _exportBmp_1bpp(const BMP_FILE *bf);
|
static int _exportBmp_1bpp(const BMP_FILE *bf);
|
||||||
static int _exportBmp_gray8bpp(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 BMP_FILEHEADER *_fileHeader_new();
|
||||||
static void _fileHeader_free(BMP_FILEHEADER *fh);
|
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)
|
int _exportBmp_1bpp(const BMP_FILE *bf)
|
||||||
{
|
{
|
||||||
const uint8_t *ptrBuffer;
|
const uint8_t *ptrBuffer;
|
||||||
uint32_t lenBuffer;
|
|
||||||
uint32_t offsPixels;
|
uint32_t offsPixels;
|
||||||
const uint8_t *ptrPixels;
|
const uint8_t *ptrPixels;
|
||||||
int imageWidth;
|
int imageWidth;
|
||||||
@@ -195,7 +200,6 @@ int _exportBmp_1bpp(const BMP_FILE *bf)
|
|||||||
int y;
|
int y;
|
||||||
|
|
||||||
ptrBuffer=(const uint8_t *) GWEN_Buffer_GetStart(bf->buffer);
|
ptrBuffer=(const uint8_t *) GWEN_Buffer_GetStart(bf->buffer);
|
||||||
lenBuffer=GWEN_Buffer_GetUsedBytes(bf->buffer);
|
|
||||||
offsPixels=bf->fileHeader->offsPixels;
|
offsPixels=bf->fileHeader->offsPixels;
|
||||||
ptrPixels=ptrBuffer+offsPixels;
|
ptrPixels=ptrBuffer+offsPixels;
|
||||||
imageWidth=bf->imageHeader->imgWidth;
|
imageWidth=bf->imageHeader->imgWidth;
|
||||||
@@ -226,34 +230,51 @@ int _exportBmp_1bpp(const BMP_FILE *bf)
|
|||||||
int _exportBmp_gray8bpp(const BMP_FILE *bf)
|
int _exportBmp_gray8bpp(const BMP_FILE *bf)
|
||||||
{
|
{
|
||||||
const uint8_t *ptrBuffer;
|
const uint8_t *ptrBuffer;
|
||||||
uint32_t lenBuffer;
|
|
||||||
uint32_t offsPixels;
|
uint32_t offsPixels;
|
||||||
const uint8_t *ptrPixels;
|
const uint8_t *ptrPixels;
|
||||||
int imageWidth;
|
int imageWidth;
|
||||||
int imageHeight;
|
int imageHeight;
|
||||||
int rowWidthInBytes;
|
GWEN_BUFFER *pixelBuf;
|
||||||
int columns;
|
GWEN_BUFFER *asmBuf;
|
||||||
int y;
|
|
||||||
|
|
||||||
ptrBuffer=(const uint8_t *) GWEN_Buffer_GetStart(bf->buffer);
|
ptrBuffer=(const uint8_t *) GWEN_Buffer_GetStart(bf->buffer);
|
||||||
lenBuffer=GWEN_Buffer_GetUsedBytes(bf->buffer);
|
|
||||||
offsPixels=bf->fileHeader->offsPixels;
|
offsPixels=bf->fileHeader->offsPixels;
|
||||||
ptrPixels=ptrBuffer+offsPixels;
|
ptrPixels=ptrBuffer+offsPixels;
|
||||||
imageWidth=bf->imageHeader->imgWidth;
|
imageWidth=bf->imageHeader->imgWidth;
|
||||||
imageHeight=bf->imageHeader->imgHeight;
|
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;
|
columns=imageWidth;
|
||||||
rowWidthInBytes=4*((columns+3)/4); /* BMPs have multiple of 4 bytes per row! */
|
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--) {
|
for (y=imageHeight-1; y>=0; y--) {
|
||||||
const uint8_t *rowPtr;
|
const uint8_t *rowPtr;
|
||||||
int x;
|
int x;
|
||||||
uint8_t currentByte=0;
|
uint8_t currentByte=0;
|
||||||
int writtenBytes=0;
|
|
||||||
int packedPixels=0;
|
int packedPixels=0;
|
||||||
|
|
||||||
fprintf(stdout, " .db ");
|
|
||||||
rowPtr=ptrPixels+(y*rowWidthInBytes);
|
rowPtr=ptrPixels+(y*rowWidthInBytes);
|
||||||
for (x=0; x<columns; x++) {
|
for (x=0; x<columns; x++) {
|
||||||
uint8_t pixel;
|
uint8_t pixel;
|
||||||
@@ -271,15 +292,122 @@ int _exportBmp_gray8bpp(const BMP_FILE *bf)
|
|||||||
currentByte|=newPix;
|
currentByte|=newPix;
|
||||||
packedPixels++;
|
packedPixels++;
|
||||||
if (packedPixels==4) {
|
if (packedPixels==4) {
|
||||||
if (writtenBytes)
|
GWEN_Buffer_AppendByte(destBuf, currentByte);
|
||||||
fprintf(stdout, ", ");
|
packedPixels=0;
|
||||||
fprintf(stdout, "0x%02x", currentByte);
|
currentByte=0;
|
||||||
writtenBytes++;
|
|
||||||
packedPixels=0;
|
|
||||||
currentByte=0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stdout, "\n");
|
}
|
||||||
|
if (GWEN_Buffer_GetUsedBytes(destBuf)==0) {
|
||||||
|
GWEN_Buffer_free(destBuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return destBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _printBytes_ASM(const char *sName, const uint8_t *ptrPixels, int lenPixels, int imageWidth, int imageHeight)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
fprintf(stdout, "%s: \n", sName);
|
||||||
|
fprintf(stdout, " .dw %d, %d ; width, height\n", imageWidth, imageHeight);
|
||||||
|
for (i=0; i<lenPixels; i++) {
|
||||||
|
uint8_t currentByte;
|
||||||
|
|
||||||
|
currentByte=ptrPixels[i];
|
||||||
|
if ((i & 15)==0) {
|
||||||
|
if (i)
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
fprintf(stdout, " .db 0x%02x", currentByte);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stdout, ", 0x%02x", currentByte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_BUFFER *_rleEncode(const uint8_t *ptrPixels, int lenPixels)
|
||||||
|
{
|
||||||
|
GWEN_BUFFER *resultBuf;
|
||||||
|
GWEN_BUFFER *currentBuf;
|
||||||
|
int numCurrentBuf;
|
||||||
|
|
||||||
|
resultBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
currentBuf=GWEN_Buffer_new(0, 128, 0, 1);
|
||||||
|
|
||||||
|
while(ptrPixels && lenPixels>0) {
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -288,6 +416,7 @@ int _exportBmp_gray8bpp(const BMP_FILE *bf)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BMP_FILE *BMP_File_new(const char *fname)
|
BMP_FILE *BMP_File_new(const char *fname)
|
||||||
{
|
{
|
||||||
BMP_FILE *bf;
|
BMP_FILE *bf;
|
||||||
|
|||||||
Reference in New Issue
Block a user