KSM edits to RA8875
Diff: RA8875.cpp
- Revision:
- 163:17526689a3ed
- Parent:
- 162:a2d7f1988711
- Child:
- 164:76edd7d9cb68
--- a/RA8875.cpp Mon Feb 11 03:44:42 2019 +0000 +++ b/RA8875.cpp Wed Feb 13 04:20:12 2019 +0000 @@ -101,6 +101,75 @@ "external abort", ///< during an idle callback, the user code initiated an abort }; +typedef struct { + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t a; +} rgbTrio_t; + +static const rgbTrio_t WebColorPalette[] = { + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x33,0xFF}, {0x00,0x00,0x66,0xFF}, {0x00,0x00,0x99,0xFF}, {0x00,0x00,0xCC,0xFF}, {0x00,0x00,0xFF,0xFF}, + {0x00,0x33,0x00,0xFF}, {0x00,0x33,0x33,0xFF}, {0x00,0x33,0x66,0xFF}, {0x00,0x33,0x99,0xFF}, {0x00,0x33,0xCC,0xFF}, {0x00,0x33,0xFF,0xFF}, + {0x00,0x66,0x00,0xFF}, {0x00,0x66,0x33,0xFF}, {0x00,0x66,0x66,0xFF}, {0x00,0x66,0x99,0xFF}, {0x00,0x66,0xCC,0xFF}, {0x00,0x66,0xFF,0xFF}, + {0x00,0x99,0x00,0xFF}, {0x00,0x99,0x33,0xFF}, {0x00,0x99,0x66,0xFF}, {0x00,0x99,0x99,0xFF}, {0x00,0x99,0xCC,0xFF}, {0x00,0x99,0xFF,0xFF}, + {0x00,0xCC,0x00,0xFF}, {0x00,0xCC,0x33,0xFF}, {0x00,0xCC,0x66,0xFF}, {0x00,0xCC,0x99,0xFF}, {0x00,0xCC,0xCC,0xFF}, {0x00,0xCC,0xFF,0xFF}, + {0x00,0xFF,0x00,0xFF}, {0x00,0xFF,0x33,0xFF}, {0x00,0xFF,0x66,0xFF}, {0x00,0xFF,0x99,0xFF}, {0x00,0xFF,0xCC,0xFF}, {0x00,0xFF,0xFF,0xFF}, + {0x33,0x00,0x00,0xFF}, {0x33,0x00,0x33,0xFF}, {0x33,0x00,0x66,0xFF}, {0x33,0x00,0x99,0xFF}, {0x33,0x00,0xCC,0xFF}, {0x33,0x00,0xFF,0xFF}, + {0x33,0x33,0x00,0xFF}, {0x33,0x33,0x33,0xFF}, {0x33,0x33,0x66,0xFF}, {0x33,0x33,0x99,0xFF}, {0x33,0x33,0xCC,0xFF}, {0x33,0x33,0xFF,0xFF}, + {0x33,0x66,0x00,0xFF}, {0x33,0x66,0x33,0xFF}, {0x33,0x66,0x66,0xFF}, {0x33,0x66,0x99,0xFF}, {0x33,0x66,0xCC,0xFF}, {0x33,0x66,0xFF,0xFF}, + {0x33,0x99,0x00,0xFF}, {0x33,0x99,0x33,0xFF}, {0x33,0x99,0x66,0xFF}, {0x33,0x99,0x99,0xFF}, {0x33,0x99,0xCC,0xFF}, {0x33,0x99,0xFF,0xFF}, + {0x33,0xCC,0x00,0xFF}, {0x33,0xCC,0x33,0xFF}, {0x33,0xCC,0x66,0xFF}, {0x33,0xCC,0x99,0xFF}, {0x33,0xCC,0xCC,0xFF}, {0x33,0xCC,0xFF,0xFF}, + {0x33,0xFF,0x00,0xFF}, {0x33,0xFF,0x33,0xFF}, {0x33,0xFF,0x66,0xFF}, {0x33,0xFF,0x99,0xFF}, {0x33,0xFF,0xCC,0xFF}, {0x33,0xFF,0xFF,0xFF}, + {0x66,0x00,0x00,0xFF}, {0x66,0x00,0x33,0xFF}, {0x66,0x00,0x66,0xFF}, {0x66,0x00,0x99,0xFF}, {0x66,0x00,0xCC,0xFF}, {0x66,0x00,0xFF,0xFF}, + {0x66,0x33,0x00,0xFF}, {0x66,0x33,0x33,0xFF}, {0x66,0x33,0x66,0xFF}, {0x66,0x33,0x99,0xFF}, {0x66,0x33,0xCC,0xFF}, {0x66,0x33,0xFF,0xFF}, + {0x66,0x66,0x00,0xFF}, {0x66,0x66,0x33,0xFF}, {0x66,0x66,0x66,0xFF}, {0x66,0x66,0x99,0xFF}, {0x66,0x66,0xCC,0xFF}, {0x66,0x66,0xFF,0xFF}, + {0x66,0x99,0x00,0xFF}, {0x66,0x99,0x33,0xFF}, {0x66,0x99,0x66,0xFF}, {0x66,0x99,0x99,0xFF}, {0x66,0x99,0xCC,0xFF}, {0x66,0x99,0xFF,0xFF}, + {0x66,0xCC,0x00,0xFF}, {0x66,0xCC,0x33,0xFF}, {0x66,0xCC,0x66,0xFF}, {0x66,0xCC,0x99,0xFF}, {0x66,0xCC,0xCC,0xFF}, {0x66,0xCC,0xFF,0xFF}, + {0x66,0xFF,0x00,0xFF}, {0x66,0xFF,0x33,0xFF}, {0x66,0xFF,0x66,0xFF}, {0x66,0xFF,0x99,0xFF}, {0x66,0xFF,0xCC,0xFF}, {0x66,0xFF,0xFF,0xFF}, + {0x99,0x00,0x00,0xFF}, {0x99,0x00,0x33,0xFF}, {0x99,0x00,0x66,0xFF}, {0x99,0x00,0x99,0xFF}, {0x99,0x00,0xCC,0xFF}, {0x99,0x00,0xFF,0xFF}, + {0x99,0x33,0x00,0xFF}, {0x99,0x33,0x33,0xFF}, {0x99,0x33,0x66,0xFF}, {0x99,0x33,0x99,0xFF}, {0x99,0x33,0xCC,0xFF}, {0x99,0x33,0xFF,0xFF}, + {0x99,0x66,0x00,0xFF}, {0x99,0x66,0x33,0xFF}, {0x99,0x66,0x66,0xFF}, {0x99,0x66,0x99,0xFF}, {0x99,0x66,0xCC,0xFF}, {0x99,0x66,0xFF,0xFF}, + {0x99,0x99,0x00,0xFF}, {0x99,0x99,0x33,0xFF}, {0x99,0x99,0x66,0xFF}, {0x99,0x99,0x99,0xFF}, {0x99,0x99,0xCC,0xFF}, {0x99,0x99,0xFF,0xFF}, + {0x99,0xCC,0x00,0xFF}, {0x99,0xCC,0x33,0xFF}, {0x99,0xCC,0x66,0xFF}, {0x99,0xCC,0x99,0xFF}, {0x99,0xCC,0xCC,0xFF}, {0x99,0xCC,0xFF,0xFF}, + {0x99,0xFF,0x00,0xFF}, {0x99,0xFF,0x33,0xFF}, {0x99,0xFF,0x66,0xFF}, {0x99,0xFF,0x99,0xFF}, {0x99,0xFF,0xCC,0xFF}, {0x99,0xFF,0xFF,0xFF}, + {0xCC,0x00,0x00,0xFF}, {0xCC,0x00,0x33,0xFF}, {0xCC,0x00,0x66,0xFF}, {0xCC,0x00,0x99,0xFF}, {0xCC,0x00,0xCC,0xFF}, {0xCC,0x00,0xFF,0xFF}, + {0xCC,0x33,0x00,0xFF}, {0xCC,0x33,0x33,0xFF}, {0xCC,0x33,0x66,0xFF}, {0xCC,0x33,0x99,0xFF}, {0xCC,0x33,0xCC,0xFF}, {0xCC,0x33,0xFF,0xFF}, + {0xCC,0x66,0x00,0xFF}, {0xCC,0x66,0x33,0xFF}, {0xCC,0x66,0x66,0xFF}, {0xCC,0x66,0x99,0xFF}, {0xCC,0x66,0xCC,0xFF}, {0xCC,0x66,0xFF,0xFF}, + {0xCC,0x99,0x00,0xFF}, {0xCC,0x99,0x33,0xFF}, {0xCC,0x99,0x66,0xFF}, {0xCC,0x99,0x99,0xFF}, {0xCC,0x99,0xCC,0xFF}, {0xCC,0x99,0xFF,0xFF}, + {0xCC,0xCC,0x00,0xFF}, {0xCC,0xCC,0x33,0xFF}, {0xCC,0xCC,0x66,0xFF}, {0xCC,0xCC,0x99,0xFF}, {0xCC,0xCC,0xCC,0xFF}, {0xCC,0xCC,0xFF,0xFF}, + {0xCC,0xFF,0x00,0xFF}, {0xCC,0xFF,0x33,0xFF}, {0xCC,0xFF,0x66,0xFF}, {0xCC,0xFF,0x99,0xFF}, {0xCC,0xFF,0xCC,0xFF}, {0xCC,0xFF,0xFF,0xFF}, + {0xFF,0x00,0x00,0xFF}, {0xFF,0x00,0x33,0xFF}, {0xFF,0x00,0x66,0xFF}, {0xFF,0x00,0x99,0xFF}, {0xFF,0x00,0xCC,0xFF}, {0xFF,0x00,0xFF,0xFF}, + {0xFF,0x33,0x00,0xFF}, {0xFF,0x33,0x33,0xFF}, {0xFF,0x33,0x66,0xFF}, {0xFF,0x33,0x99,0xFF}, {0xFF,0x33,0xCC,0xFF}, {0xFF,0x33,0xFF,0xFF}, + {0xFF,0x66,0x00,0xFF}, {0xFF,0x66,0x33,0xFF}, {0xFF,0x66,0x66,0xFF}, {0xFF,0x66,0x99,0xFF}, {0xFF,0x66,0xCC,0xFF}, {0xFF,0x66,0xFF,0xFF}, + {0xFF,0x99,0x00,0xFF}, {0xFF,0x99,0x33,0xFF}, {0xFF,0x99,0x66,0xFF}, {0xFF,0x99,0x99,0xFF}, {0xFF,0x99,0xCC,0xFF}, {0xFF,0x99,0xFF,0xFF}, + {0xFF,0xCC,0x00,0xFF}, {0xFF,0xCC,0x33,0xFF}, {0xFF,0xCC,0x66,0xFF}, {0xFF,0xCC,0x99,0xFF}, {0xFF,0xCC,0xCC,0xFF}, {0xFF,0xCC,0xFF,0xFF}, + {0xFF,0xFF,0x00,0xFF}, {0xFF,0xFF,0x33,0xFF}, {0xFF,0xFF,0x66,0xFF}, {0xFF,0xFF,0x99,0xFF}, {0xFF,0xFF,0xCC,0xFF}, {0xFF,0xFF,0xFF,0xFF}, + + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, + {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, +}; + +#define sqr(a) (double)((a) * (a)) + +static int FindNearestWebColor(uint8_t r, uint8_t g, uint8_t b) { + int bestNdx = 0; + float bestDiff = sqrt(sqr(r - WebColorPalette[0].r) + sqr(g - WebColorPalette[0].g) + sqr(b - WebColorPalette[0].b)); + for (int i=1; i<216; i++) { + float thisDiff = sqrt(sqr(r - WebColorPalette[i].r) + sqr(g - WebColorPalette[i].g) + sqr(b - WebColorPalette[i].b)); + if (thisDiff < bestDiff) { + bestDiff = thisDiff; + bestNdx = i; + } + } + return bestNdx; +} + RA8875::RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, const char *name) : GraphicsDisplay(name) @@ -2241,7 +2310,8 @@ } } -RetCode_t RA8875::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP) + +RetCode_t RA8875::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP, uint8_t bitsPerPixel) { BITMAPFILEHEADER BMP_Header; BITMAPINFOHEADER BMP_Info; @@ -2249,33 +2319,49 @@ color_t * pixelBuffer = NULL; color_t * pixelBuffer2 = NULL; - INFO("(%d,%d) - (%d,%d) %s", x,y,w,h,Name_BMP); + INFO("(%d,%d)-(%d,%d)x%d %s", x,y,w,h,bitsPerPixel,Name_BMP); if (x >= 0 && x < screenwidth && y >= 0 && y < screenheight && w > 0 && x + w <= screenwidth && h > 0 && y + h <= screenheight) { - BMP_Header.bfType = BF_TYPE; - BMP_Header.bfSize = (w * h * sizeof(RGBQUAD)) + sizeof(BMP_Header) + sizeof(BMP_Info); BMP_Header.bfReserved1 = 0; BMP_Header.bfReserved2 = 0; - BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Info); + switch (bitsPerPixel) { + case 24: + BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Info); + BMP_Header.bfSize = (h * RoundUp(w * sizeof(RGBQUAD),4)) + BMP_Header.bfOffBits; + break; + case 8: + default: + BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Info) + sizeof(WebColorPalette); + INFO("Initial Offset to Bitstream %X", BMP_Header.bfOffBits); + //if (BMP_Header.bfOffBits & 0x03) { + // BMP_Header.bfOffBits += (4 - (BMP_Header.bfOffBits & 0x03)); + //} + BMP_Header.bfSize = (h * RoundUp(w * 1,4)) + BMP_Header.bfOffBits; + break; + } + INFO("Offset to Bitstream %X", BMP_Header.bfOffBits); // Bytes in the line buffer - int lineBufSize = RoundUp(3 * w, 4); // ((24 * w + 7)/8); + int lineBufSize = RoundUp(((bitsPerPixel == 24) ? 3 : 1) * w, 4); INFO("LineBufSize: %d", lineBufSize); BMP_Info.biSize = sizeof(BMP_Info); BMP_Info.biWidth = w; BMP_Info.biHeight = h; BMP_Info.biPlanes = 1; - BMP_Info.biBitCount = 24; + BMP_Info.biBitCount = bitsPerPixel; BMP_Info.biCompression = BI_RGB; BMP_Info.biSizeImage = lineBufSize * h; BMP_Info.biXPelsPerMeter = 0; BMP_Info.biYPelsPerMeter = 0; - BMP_Info.biClrUsed = 0; - BMP_Info.biClrImportant = 0; + // for 24-bit, there is no palette, so these are zero + // for 8-bit, there can be up to 256 RGB values in the palette + + BMP_Info.biClrUsed = (bitsPerPixel == 24) ? 0 : sizeof(WebColorPalette)/sizeof(WebColorPalette[0]); // for 8b/pixel + BMP_Info.biClrImportant = BMP_Info.biClrUsed; // Allocate the memory we need to proceed lineBuffer = (uint8_t *)swMalloc(lineBufSize); @@ -2329,7 +2415,16 @@ HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info)); fwrite(&BMP_Info, sizeof(char), sizeof(BMP_Info), Image); - + + if (bitsPerPixel != 24) { + HexDump("Palette", (uint8_t *)&WebColorPalette, sizeof(WebColorPalette)); + fwrite(&WebColorPalette, sizeof(char), sizeof(WebColorPalette), Image); + if (0 && sizeof(WebColorPalette) % 4) { + const uint8_t padd[] = { 0, 0, 0 }; + fwrite(&padd, sizeof(char), + (sizeof(BMP_Header) + sizeof(BMP_Info) + sizeof(WebColorPalette)) % 4, Image); + } + } //color_t transparency = GetBackgroundTransparencyColor(); LayerMode_T ltpr0 = GetLayerMode(); @@ -2366,7 +2461,7 @@ } } INFO("Line: %3d", j); - HexDump("Raster", (uint8_t *)pixelBuffer, w * sizeof(color_t)); + //HexDump("Raster", (uint8_t *)pixelBuffer, w * sizeof(color_t)); // Convert the local buffer to RGBQUAD format int lb = 0; for (int i=0; i<w; i++) { @@ -2382,25 +2477,36 @@ case 2: // lighten-overlay (@TODO Not supported yet) case 6: // Floating Windows (@TODO not sure how to support) default: // Reserved... + //lineBuffer[lb++] = q0.rgbBlue; + //lineBuffer[lb++] = q0.rgbGreen; + //lineBuffer[lb++] = q0.rgbRed; + break; + case 3: // transparent mode (@TODO Read the background color register for transparent) + case 4: // boolean or + q0.rgbBlue = q0.rgbBlue | q1.rgbBlue; + q0.rgbGreen = q0.rgbGreen | q1.rgbGreen; + q0.rgbRed = q0.rgbRed | q1.rgbRed; + break; + case 5: // boolean AND + q0.rgbBlue = q0.rgbBlue & q1.rgbBlue; + q0.rgbGreen = q0.rgbGreen & q1.rgbGreen; + q0.rgbRed = q0.rgbRed & q1.rgbRed; + break; + } + switch (bitsPerPixel) { + case 24: lineBuffer[lb++] = q0.rgbBlue; lineBuffer[lb++] = q0.rgbGreen; lineBuffer[lb++] = q0.rgbRed; break; - case 3: // transparent mode (@TODO Read the background color register for transparent) - case 4: // boolean or - lineBuffer[lb++] = q0.rgbBlue | q1.rgbBlue; - lineBuffer[lb++] = q0.rgbGreen | q1.rgbGreen; - lineBuffer[lb++] = q0.rgbRed | q1.rgbRed; - break; - case 5: // boolean AND - lineBuffer[lb++] = q0.rgbBlue & q1.rgbBlue; - lineBuffer[lb++] = q0.rgbGreen & q1.rgbGreen; - lineBuffer[lb++] = q0.rgbRed & q1.rgbRed; + case 8: + default: + lineBuffer[lb++] = FindNearestWebColor(q0.rgbRed,q0.rgbGreen,q0.rgbBlue); break; } } //if (j == h - 1) { - HexDump("Line", lineBuffer, lineBufSize); + // HexDump("Line", lineBuffer, lineBufSize); //} // Write to disk fwrite(lineBuffer, sizeof(char), lineBufSize, Image);