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_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; x<columns; x++) {
|
||||
uint8_t pixel;
|
||||
@@ -271,15 +292,122 @@ int _exportBmp_gray8bpp(const BMP_FILE *bf)
|
||||
currentByte|=newPix;
|
||||
packedPixels++;
|
||||
if (packedPixels==4) {
|
||||
if (writtenBytes)
|
||||
fprintf(stdout, ", ");
|
||||
fprintf(stdout, "0x%02x", currentByte);
|
||||
writtenBytes++;
|
||||
packedPixels=0;
|
||||
currentByte=0;
|
||||
GWEN_Buffer_AppendByte(destBuf, currentByte);
|
||||
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;
|
||||
}
|
||||
@@ -288,6 +416,7 @@ int _exportBmp_gray8bpp(const BMP_FILE *bf)
|
||||
|
||||
|
||||
|
||||
|
||||
BMP_FILE *BMP_File_new(const char *fname)
|
||||
{
|
||||
BMP_FILE *bf;
|
||||
|
||||
Reference in New Issue
Block a user