Forked para SNOCC
Fork of RA8875 by
Diff: RA8875.cpp
- Revision:
- 96:40b74dd3695b
- Parent:
- 95:ef538bd687c0
- Child:
- 97:03c509c3db18
- Child:
- 98:ecebed9b80b2
diff -r ef538bd687c0 -r 40b74dd3695b RA8875.cpp --- a/RA8875.cpp Tue Jul 07 17:05:59 2015 +0000 +++ b/RA8875.cpp Sat Nov 28 15:39:44 2015 +0000 @@ -97,6 +97,9 @@ , cs(csel) , res(reset) { + c_callback = NULL; + obj_callback = NULL; + method_callback = NULL; } //RA8875::~RA8875() @@ -1587,9 +1590,205 @@ RetCode_t RA8875::PrintScreen(uint16_t layer, loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP) { (void)layer; + + // AttachPrintHandler(this, RA8875::_printCallback); + // return PrintScreen(x,y,w,h); return PrintScreen(x, y, w, h, Name_BMP); } +RetCode_t RA8875::_printCallback(RA8875::filecmd_t cmd, uint8_t * buffer, uint16_t size) +{ + HexDump("CB", buffer, size); + switch(cmd) { + case RA8875::OPEN: + //pc.printf("About to write %lu bytes\r\n", *(uint32_t *)buffer); + _printFH = fopen("file.bmp", "w+b"); + if (_printFH == 0) + return file_not_found; + break; + case RA8875::WRITE: + //pc.printf(" Write %4u bytes\r\n", size); + fwrite(buffer, 1, size, _printFH); + break; + case RA8875::CLOSE: + //pc.printf(" close\r\n"); + fclose(_printFH); + _printFH = 0; + break; + default: + //pc.printf("Unexpected callback %d\r\n", cmd); + return file_not_found; + //break; + } + return noerror; +} + +RetCode_t RA8875::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h) +{ + BITMAPFILEHEADER BMP_Header; + BITMAPINFOHEADER BMP_Info; + uint8_t * lineBuffer = NULL; + color_t * pixelBuffer = NULL; + color_t * pixelBuffer2 = NULL; + + INFO("(%d,%d) - (%d,%d) %s", x,y,w,h,Name_BMP); + if (x >= 0 && x < width() + && y >= 0 && y < height() + && w > 0 && x + w <= width() + && h > 0 && y + h <= height()) { + + BMP_Header.bfType = BF_TYPE; + BMP_Header.bfSize = (w * h * sizeof(RGBQUAD)) + sizeof(BMP_Header) + sizeof(BMP_Header); + BMP_Header.bfReserved1 = 0; + BMP_Header.bfReserved2 = 0; + BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Header); + + BMP_Info.biSize = sizeof(BMP_Info); + BMP_Info.biWidth = w; + BMP_Info.biHeight = h; + BMP_Info.biPlanes = 1; + BMP_Info.biBitCount = 24; + BMP_Info.biCompression = BI_RGB; + BMP_Info.biSizeImage = 0; + BMP_Info.biXPelsPerMeter = 0; + BMP_Info.biYPelsPerMeter = 0; + BMP_Info.biClrUsed = 0; + BMP_Info.biClrImportant = 0; + + // Allocate the memory we need to proceed + int lineBufSize = ((24 * w + 7)/8); + lineBuffer = (uint8_t *)malloc(lineBufSize); + if (lineBuffer == NULL) { + ERR("Not enough RAM for PrintScreen lineBuffer"); + return(not_enough_ram); + } + + #define DOUBLEBUF /* one larger buffer instead of two */ + + #ifdef DOUBLEBUF + // In the "#else", pixelBuffer2 malloc returns a value, + // but is actually causing a failure later. + // This test helps determine if it is truly out of memory, + // or if malloc is broken. + pixelBuffer = (color_t *)malloc(2 * w * sizeof(color_t)); + pixelBuffer2 = pixelBuffer + (w * sizeof(color_t)); + #else + pixelBuffer = (color_t *)malloc(w * sizeof(color_t)); + pixelBuffer2 = (color_t *)malloc(w * sizeof(color_t)); + #endif + if (pixelBuffer == NULL || pixelBuffer2 == NULL) { + ERR("Not enough RAM for pixelBuffer"); + #ifndef DOUBLEBUF + if (pixelBuffer2) + free(pixelBuffer2); + #endif + if (pixelBuffer) + free(pixelBuffer); + free(lineBuffer); + if (pixelBuffer) + free(pixelBuffer); + return(not_enough_ram); + } + + // Get the file primed... + privateCallback(OPEN, (uint8_t *)&BMP_Header.bfSize, 4); + + // Be optimistic - don't check for errors. + HexDump("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header)); + //fwrite(&BMP_Header, sizeof(char), sizeof(BMP_Header), Image); + privateCallback(WRITE, (uint8_t *)&BMP_Header, sizeof(BMP_Header)); + + HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info)); + //fwrite(&BMP_Info, sizeof(char), sizeof(BMP_Info), Image); + privateCallback(WRITE, (uint8_t *)&BMP_Info, sizeof(BMP_Info)); + + //color_t transparency = GetBackgroundTransparencyColor(); + LayerMode_T ltpr0 = GetLayerMode(); + + uint16_t prevLayer = GetDrawingLayer(); + // If only one of the layers is visible, select that layer + switch(ltpr0) { + case ShowLayer0: + SelectDrawingLayer(0); + break; + case ShowLayer1: + SelectDrawingLayer(1); + break; + default: + break; + } + + // Read the display from the last line toward the top + // so we can write the file in one pass. + for (int j = h - 1; j >= 0; j--) { + if (ltpr0 >= 2) // Need to combine the layers... + SelectDrawingLayer(0); // so read layer 0 first + // Read one line of pixels to a local buffer + if (getPixelStream(pixelBuffer, w, x,y+j) != noerror) { + ERR("getPixelStream error, and no recovery handler..."); + } + if (ltpr0 >= 2) { // Need to combine the layers... + SelectDrawingLayer(1); // so read layer 1 next + if (getPixelStream(pixelBuffer2, w, x,y+j) != noerror) { + ERR("getPixelStream error, and no recovery handler..."); + } + } + INFO("1st Color: %04X", pixelBuffer[0]); + HexDump("Raster", (uint8_t *)pixelBuffer, w); + // Convert the local buffer to RGBQUAD format + int lb = 0; + for (int i=0; i<w; i++) { + RGBQUAD q0 = RGB16ToRGBQuad(pixelBuffer[x+i]); // Scale to 24-bits + RGBQUAD q1 = RGB16ToRGBQuad(pixelBuffer2[x+i]); // Scale to 24-bits + switch (ltpr0) { + case 0: + case 1: + 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 + 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; + break; + } + } + if (j == h - 1) { + HexDump("Line", lineBuffer, lineBufSize); + } + // Write to disk + //fwrite(lineBuffer, sizeof(char), lb, Image); + privateCallback(WRITE, (uint8_t *)lineBuffer, lb); + } + SelectDrawingLayer(prevLayer); + //fclose(Image); + privateCallback(CLOSE, NULL, 0); + + #ifndef DOUBLEBUF + if (pixelBuffer2) + free(pixelBuffer2); + #endif + if (pixelBuffer) + free(pixelBuffer); + free(lineBuffer); + if (pixelBuffer) + free(pixelBuffer); + INFO("Image closed"); + return noerror; + } else { + return bad_parameter; + } +} RetCode_t RA8875::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP) {