/*Understand, Correct, Improve ___ ________/| _________________/\__/\____/ /_____ \ ____/ |/ __/ / / __ / \/ \ \ / __/ | __/ /\__ \ / __ \ / \ _/ \ |___\ \__\____ //__/\_____/\ /__/\ /_____/ `-------------\/------breeze-\ /crew-\/------' \/ BMP to SXG (Speccy eXtended Graphics) [PentEvo 256] ---------------------------------------------------------- Written by breeze \ fishbone crew | http://fishbone.untergrund.net/ breeze@tut.by 18.02.2015 */ #include #include #include #include //--------------------------------------------------------------------------------------------- void printBits(char number){ char *bitsStr = "00000000\0"; for (int pos=8; pos>0; pos--) { if(number > 0){ bitsStr[pos-1] = '0' + (number%2); number = number/2; } else { bitsStr[pos-1] = '0'; } } printf(bitsStr); } unsigned int fileLength(FILE *f) { int pos; int end; pos = ftell (f); fseek (f, 0, SEEK_END); end = ftell (f); fseek (f, pos, SEEK_SET); return end; } void printStrint (char *str) { for (int i=0; str[i] != '\0'; i++){ printf ("%c", str[i]); } } bool testHex (char testChar) { bool valid = false; if ((testChar > 0x2F && testChar < 0x39) || (testChar > 0x40 && testChar < 0x47)) { valid = true; } return valid; } //--------------------------------------------------------------------------------------------- int main (int argc, char *argv[]) { char *filename = NULL; bool debugMode = false; bool enableShim = true; if ((argc > 1) && (argv[1][0] != '-')) { filename = argv[1]; ++argv; --argc; } while ((argc > 1) && (argv[1][0] == '-' && argv[1][1] == '-')) { //printf("arg %d = param %s\n", argc, argv[1]); if (strcmp (argv[1], "--debug") == 0) { debugMode = true; } else if (strcmp (argv[1], "--64") == 0) { enableShim = false; } ++argv; --argc; } // \033[22;30m - black // \033[22;31m - red // \033[22;32m - green // \033[22;33m - brown // \033[22;34m - blue // \033[22;35m - magenta // \033[22;36m - cyan // \033[22;37m - gray // \033[01;30m - dark gray // \033[01;31m - light red // \033[01;32m - light green // \033[01;33m - yellow // \033[01;34m - light blue // \033[01;35m - light magenta // \033[01;36m - light cyan // \033[01;37m - white printf("\nBMP to SXG (Speccy eXtended Graphics) v0.4 (alpha) 18 Feb 2015\n"); printf("-----------------------------------------------------------------------------------\n"); printf("Written by breeze\\fishbone crew | fishbone@speccy.su | http://fishbone.untergrund.net/\n"); printf("\n"); if (filename == NULL) { printf("Usage: bmp2sxg [commands]\n"); printf("Commands:\n"); printf(" --debug enable output debug information (default disabled)\n"); printf(" --64 cut palette to atm 64 colors limit (default disabled)\n"); } else { printf("Debug: "); if (debugMode) { printf("Enabled\n"); } else { printf("Disabled\n"); } printf("Full colors: "); if (enableShim) { printf("Enabled\n"); } else { printf("Disabled\n"); } printf("Work file: %s ", filename); FILE *readfile = fopen(filename, "rb"); if (readfile != NULL) { unsigned int filelen = fileLength(readfile); if (filelen > 0) { printf("(%i bytes)\n", filelen); void *fileContent = malloc( filelen + 1 ); fread(fileContent, filelen, 1, readfile); fclose(readfile); memcpy ((void *)((unsigned int)fileContent + filelen), "\0", 1); printf ("File analizing... "); unsigned char *bmpData = (unsigned char *)fileContent; unsigned char *beginData = (unsigned char *)fileContent; if (*(bmpData) == 'B' && *(bmpData+1) == 'M') { bmpData += 2; printf("BMP format detected!\n"); unsigned long bmpSize = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; bmpData += 4; // reserved 4 bytes unsigned long imageStart = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long headerSize = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long bmpWidth = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long bmpHeigth = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned short bmpLayers = *(bmpData) + (*(bmpData+1)*256); bmpData += 2; unsigned short bmpBits = *(bmpData) + (*(bmpData+1)*256); bmpData += 2; unsigned long bmpCompressType = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long bmpCompressSize = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long bmpHorizontal = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long bmpVertical = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long bmpColors = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; unsigned long bmpColorsActive = (*(bmpData) + (*(bmpData+1)*256)) + (*(bmpData+2) + (*(bmpData+3)*256))*256; bmpData += 4; printf("\nBMP header:\n"); printf("---------------------------------\n"); printf (" file size: %d bytes\n", bmpSize); printf (" image width: %d px\n", bmpWidth); printf (" image heigth: %d px\n", bmpHeigth); printf (" image planes: %d\n", bmpLayers); printf (" bits/pixel: %d\n", bmpBits); //printf (" compress type: %d (0-NO, 1-RLE8, 2 - RLE4)\n", bmpCompressType); printf (" compress type: %d ", bmpCompressType); switch (bmpCompressType) { case 0: printf ("(none)"); break; case 1: printf ("(RLE 8-bit/pixel)"); break; case 2: printf ("(RLE 4-bit/pixel)"); break; case 3: printf ("(Bit field or Huffman 1D compression for BITMAPCOREHEADER2)"); break; case 4: printf ("(JPEG or RLE-24 compression for BITMAPCOREHEADER2)"); break; case 5: printf ("(PNG)"); break; case 6: printf ("(Bit field)"); break; default: printf ("(unknown)"); } printf ("\n"); printf (" image size: %d bytes\n", bmpCompressSize); printf (" x pixels per meter: %d\n", bmpHorizontal); printf (" y pixels per meter: %d\n", bmpVertical); printf (" colors in color table: %d\n", bmpColors); printf (" important color count: %d\n\n", bmpColorsActive); if (bmpCompressType == 0) { printf("BMP palette:\n"); printf("---------------------------------\n"); unsigned char realColorz = bmpColors; if ( realColorz == 0 ) { realColorz = bmpBits * bmpBits; } if (realColorz > 0) { unsigned char colorz[realColorz*2]; printf ("BMP use calculated colors: %d\n\n", realColorz); if (debugMode) { printf (" No # R G B R G B pentevo xRRrrrGG gggBBbbb\n"); } int index = 0; for (int i = 0; i ",r,g,b); } unsigned char colorCodeL = 0; unsigned char colorCodeH = 0; r = (r/10.6 + 0.5); g = (g/10.6 + 0.5); b = (b/10.6 + 0.5); if (enableShim) { colorCodeL = (b & 31) | ((g & 7)<<5); colorCodeH = ((r & 31)<<2) | ((g & 31)>>3); } else { colorCodeL = (b & 24); colorCodeH = ((r & 24)<<2) | ((g & 24)>>3); } if (debugMode) { printf("%3d,%3d,%3d ",r,g,b); printf("-> %3d,%3d[#%02X%02X] ", colorCodeH, colorCodeL, colorCodeH, colorCodeL); printBits(colorCodeH); printf(" "); printBits(colorCodeL); printf("\n"); } colorz[index] = colorCodeL; index++; colorz[index] = colorCodeH; index++; } printf("\nBMP Bitmap data...\n"); printf("---------------------------------\n"); // bmpBits 1 - bitmap is monochrome // bmpBits 4 - bitmap has a maximum of 16 colors // bmpBits 8 - bitmap has a maximum of 256 colors // bmpBits 16 - bitmap has a maximum of 65536 colors // bmpBits 32 - bitmap has a maximum of 16777216 colors printf("Bitmap bits - %d \n", bmpBits); if (bmpBits == 4 || bmpBits == 8) { unsigned long dataLen = ( bmpWidth * bmpHeigth ); if ( dataLen > 0 ) { if (bmpBits == 4) { dataLen = dataLen/2; } printf("Bitmap data length - %d bytes\n", dataLen); unsigned char *bmpImageData=(unsigned char *)(beginData+imageStart); unsigned char *memImageData = (unsigned char *)malloc(dataLen); unsigned char *workImageData = (unsigned char *)(memImageData); unsigned long spriteWidth = bmpWidth; if (bmpBits == 4) { spriteWidth = bmpWidth / 2; } for (int y = bmpHeigth - 1; y >= 0; y-- ) { for (int x = 0; x < spriteWidth; x++){ unsigned char colorPixel = *(bmpImageData + x + ( y * spriteWidth )); *workImageData = colorPixel; workImageData++; if (debugMode) { printf("#%02X,",colorPixel); } } if (debugMode) { printf("\n"); } } unsigned char colorzFinal[realColorz*2]; for (int i=0; i 4) { sxgType = 2; } fwrite(&sxgType, 1, 1, writeSxgFile); short int sxgWidth = (short int)bmpWidth; short int sxgHeigth = (short int)bmpHeigth; fwrite(&bmpWidth, 1, sizeof(short int), writeSxgFile); fwrite(&bmpHeigth, 1, sizeof(short int), writeSxgFile); short int palStart = 2; fwrite(&palStart, 1, sizeof(short int), writeSxgFile); short int palSize = realColorz*2; fwrite(&palSize, 1, sizeof(short int), writeSxgFile); fwrite(colorzFinal, 1, palSize, writeSxgFile); workImageData = memImageData; unsigned long writeLen = dataLen; fwrite(workImageData, 1, writeLen, writeSxgFile); } else { printf ("Error: Can't write file: %s", saveFileName); } free (memImageData); } else { printf("Error: Wrong bitmap legth!\n"); return 1; } } else { printf("Error: support only 16 & 256 colors bmp!\n"); return 1; } } else { printf("Error: Wrong BMP palette.\n"); return 1; } } else { printf("Error: Compressed file not supported yet.\n"); return 1; } } else { printf("Error: Wrong format of file - %s\n", filename); return 1; } free (fileContent); } else { printf ("Error: Wrong size of file - %s\n", filename); return 1; } } else { printf ("Error: Can't opening file - %s\n", filename); return 1; } } return 0; }