Fix handling of NFTR bit depths that aren't 1,2,4

This commit is contained in:
Garhoogin 2025-05-08 01:17:02 -05:00 committed by GitHub
parent 63acfd3b09
commit afb9b74eb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 29 deletions

View File

@ -545,10 +545,11 @@ static void NftrReadNftrGlyph(NFTR_GLYPH *glyph, NFTR *nftr, const unsigned char
}
//read glyph bits
unsigned int pxPerByte = 8 / (nftr->bpp);
const unsigned char *bmp = glyphs + glyphSize * gidx;
if (nftr->header.format == NFTR_TYPE_GF_NFTR_11) bmp += 3;
/*
unsigned int pxPerByte = 8 / (nftr->bpp);
for (int y = 0; y < nftr->cellHeight; y++) {
for (int x = 0; x < nftr->cellWidth; x++) {
unsigned int pxno = x + y * nftr->cellWidth;
@ -557,6 +558,24 @@ static void NftrReadNftrGlyph(NFTR_GLYPH *glyph, NFTR *nftr, const unsigned char
unsigned int bitno = (pxPerByte - 1 - (pxno % pxPerByte)) * nftr->bpp;
glyph->px[x + y * nftr->cellWidth] = (bmp[byteno] >> bitno) & ((1 << nftr->bpp) - 1);
}
}*/
unsigned int mask = (1 << nftr->bpp) - 1;
for (int y = 0; y < nftr->cellHeight; y++) {
for (int x = 0; x < nftr->cellWidth; x++) {
int pxno = x + y * nftr->cellWidth;
//
unsigned int pxval = 0;
for (int i = 0; i < nftr->bpp; i++) {
int bitno = pxno * nftr->bpp + i;
unsigned int bit = (bmp[bitno / 8] >> (7 - (bitno % 8))) & 1;
pxval |= bit << (nftr->bpp - 1 - i);
}
glyph->px[x + y * nftr->cellWidth] = pxval;
}
}
}
@ -783,9 +802,12 @@ void NftrEnsureSorted(NFTR *nftr) {
void NftrSetBitDepth(NFTR *nftr, int depth) {
//check invalid depth or same depth
if (depth != 1 && depth != 2 && depth != 4) return;
if (depth > 8) return;
if (depth == nftr->bpp) return;
unsigned int maxNewDepth = (1 << depth) - 1;
unsigned int maxOldDepth = (1 << nftr->bpp) - 1;
//update pixel data
for (int i = 0; i < nftr->nGlyph; i++) {
NFTR_GLYPH *glyph = &nftr->glyphs[i];
@ -793,15 +815,7 @@ void NftrSetBitDepth(NFTR *nftr, int depth) {
int nPx = nftr->cellWidth * nftr->cellHeight;
for (int j = 0; j < nPx; j++) {
int curdepth = nftr->bpp;
while (depth < curdepth) {
curdepth /= 2;
px[j] = (px[j] >> curdepth);
}
while (depth > curdepth) {
px[j] = (px[j] << curdepth) | (px[j]);
curdepth *= 2;
}
px[j] = (px[j] * maxNewDepth * 2 + maxOldDepth) / (maxOldDepth * 2);
}
}
@ -851,21 +865,26 @@ static void NftrWriteGlyphToBytes(unsigned char *buf, NFTR *nftr, NFTR_GLYPH *gl
}
unsigned char pxmask = (1 << nftr->bpp) - 1;
unsigned int pxPerByte = 8 / nftr->bpp;
unsigned char pxXor = 0;
if (isJNFR) pxXor = 0xFF; // invert pixel color for JNFR
if (isJNFR) pxXor = pxmask; // invert pixel color for JNFR
unsigned int pxPerByte = 8 / nftr->bpp;
for (int y = 0; y < nftr->cellHeight; y++) {
for (int x = 0; x < nftr->cellWidth; x++) {
unsigned int pxno = x + y * nftr->cellWidth;
unsigned char pxval = (glyph->px[pxno] ^ pxXor) & pxmask;
if (isJNFR) {
//JNFR format glyphs: store at least significant bits first
buf[pxOffs + pxno / pxPerByte] |= pxval << ((pxno % pxPerByte) * nftr->bpp);
} else {
//else: store as most significant bits first
buf[pxOffs + pxno / pxPerByte] |= pxval << ((pxPerByte - 1 - (pxno % pxPerByte)) * nftr->bpp);
unsigned char pxval = glyph->px[pxno] ^ pxXor;
for (int i = 0; i < nftr->bpp; i++) {
int bitno = pxno * nftr->bpp + i;
unsigned int bit = (pxval >> (nftr->bpp - 1 - i)) & 1;
if (isJNFR) {
//JNFR is storing at the least significant bits first
buf[pxOffs + bitno / 8] |= bit << (bitno % 8);
} else {
//NFTR is storing at the most significant bits first
buf[pxOffs + bitno / 8] |= bit << (7 - (bitno % 8));
}
}
}
}

View File

@ -657,12 +657,7 @@ static void NftrViewerSetBitDepth(NFTRVIEWERDATA *data, int depth, BOOL setDropd
//update dropdown
if (setDropdown) {
//set font parameters
int bppsel = 0;
switch (depth) {
case 1: bppsel = 0; break;
case 2: bppsel = 1; break;
case 4: bppsel = 2; break;
}
int bppsel = depth - 1;
SendMessage(data->hWndDepthList, CB_SETCURSEL, bppsel, 0);
}
@ -795,7 +790,7 @@ static void NftrViewerOnCreate(NFTRVIEWERDATA *data) {
RECT posCellEditor;
NftrViewerCalcPosCellEditor(data, &posCellEditor);
LPWSTR depths[] = { L"1", L"2", L"4" };
LPWSTR depths[] = { L"1", L"2", L"3", L"4", L"5", L"6", L"7" };
data->hWndMargin = CreateWindow(NFTR_VIEWER_MARGIN_CLASS, L"", WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
posCellEditor.left, posCellEditor.top, posCellEditor.right - posCellEditor.left, posCellEditor.bottom - posCellEditor.top,
@ -1710,7 +1705,7 @@ static void NftrViewerCmdSetBitDepth(HWND hWnd, HWND hWndCtl, int notif, void *p
//set bit depth
NFTRVIEWERDATA *data = (NFTRVIEWERDATA *) param;
int sel = SendMessage(hWndCtl, CB_GETCURSEL, 0, 0);
int depth = 1 << sel;
int depth = sel + 1;
NftrViewerSetBitDepth(data, depth, FALSE);
}

View File

@ -29,7 +29,7 @@ typedef struct NFTRVIEWERDATA_ {
int spaceX; // text preview space X
int spaceY; // text preview space Y
COLOR palette[16]; // color palette to render with
COLOR palette[256]; // color palette to render with
COLORREF dlgCustomColors[16];
HWND hWndMargin;