|
|
1.1 ! root 1: /* ! 2: Hatari ! 3: ! 4: PCX Screen Shot File Output ! 5: */ ! 6: ! 7: #include "main.h" ! 8: #include "file.h" ! 9: #include "memAlloc.h" ! 10: #include "misc.h" ! 11: #include "screen.h" ! 12: ! 13: // PCX File Header ! 14: typedef struct { ! 15: char Manufact; ! 16: char Version; ! 17: char Encoded; ! 18: char BitsPerPixel; ! 19: short int XMin,YMin; ! 20: short int XMax,YMax; ! 21: short int HRes,VRes; ! 22: char Colours[16*3]; ! 23: char Reserved; ! 24: char NumPlanes; ! 25: short int BytesPerLine; ! 26: short int PaletteInfo; ! 27: char Filler[58]; ! 28: } PCXHEADER; ! 29: ! 30: //----------------------------------------------------------------------- ! 31: /* ! 32: Compress PCX planes using RLE compression ! 33: */ ! 34: unsigned char *PCX_CompressPlanes(unsigned char *pSingleRGBLine, unsigned char *pCompressedData, int nBytesPerLine) ! 35: { ! 36: unsigned char *pRGBLine; ! 37: BOOL bDoingRun; ! 38: int nPixels=0,nRunLength=0; ! 39: unsigned char Pixel; ! 40: int x; ! 41: ! 42: // Compress planes ! 43: pRGBLine = (unsigned char *)pSingleRGBLine; ! 44: bDoingRun = FALSE; ! 45: for(x=0; x<nBytesPerLine; x++) { ! 46: Pixel = *pRGBLine++; ! 47: if (bDoingRun) { ! 48: if ( (Pixel==nPixels) && (nRunLength<63) ) { // Continue run ! 49: nRunLength++; ! 50: } ! 51: else { ! 52: // Store run, if pixel differs or runlength is 63 ! 53: *pCompressedData++ = 0xC0 | nRunLength; ! 54: *pCompressedData++ = nPixels; ! 55: bDoingRun = FALSE; // Force next code to output ! 56: } ! 57: } ! 58: ! 59: if (!bDoingRun) { ! 60: if ( (Pixel==*pRGBLine) || (Pixel>=0xC0) ) { // Start run ! 61: nRunLength = 1; ! 62: nPixels = Pixel; ! 63: bDoingRun = TRUE; ! 64: } ! 65: else { ! 66: // Just store pixel ! 67: *pCompressedData++ = Pixel; ! 68: } ! 69: } ! 70: } ! 71: ! 72: // Complete run ! 73: if (bDoingRun) { ! 74: *pCompressedData++ = 0xC0 | nRunLength; ! 75: *pCompressedData++ = nPixels; ! 76: } ! 77: ! 78: return(pCompressedData); ! 79: } ! 80: ! 81: //----------------------------------------------------------------------- ! 82: /* ! 83: Save screen shot as .PCX ! 84: */ ! 85: void PCX_SaveScreenShot(char *pszFileName) ! 86: { ! 87: /* FIXME */ ! 88: /* ! 89: PCXHEADER *pPCXHeader; ! 90: unsigned short int *pSrcImage; ! 91: unsigned char *pSingleRGBLine, *pWorkRGBLine_Red, *pWorkRGBLine_Green, *pWorkRGBLine_Blue; ! 92: unsigned char *pCompressedPCX, *pCompressedData; ! 93: unsigned short int Pixel; ! 94: unsigned short int Red,Green,Blue; ! 95: int x,y,nBytesPerLine; ! 96: ! 97: // Allocate workspace for compression, over-estimate for compressed data ! 98: pSingleRGBLine = (unsigned char *)Memory_Alloc(1024*3); ! 99: pCompressedData = pCompressedPCX = (unsigned char *)Memory_Alloc((ScreenBMP.InfoHeader.biWidth*abs(ScreenBMP.InfoHeader.biHeight)*3)*2); ! 100: ! 101: // Create our PCX header ! 102: pPCXHeader = (PCXHEADER *)pCompressedData; ! 103: pCompressedData += sizeof(PCXHEADER); ! 104: Memory_Clear(pPCXHeader,sizeof(PCXHEADER)); ! 105: pPCXHeader->Manufact = 10; // ZSoft PCX ! 106: pPCXHeader->Version = 5; ! 107: pPCXHeader->Encoded = 1; // RLE encoding ! 108: pPCXHeader->BitsPerPixel = 8; ! 109: pPCXHeader->XMin = 0; ! 110: pPCXHeader->YMin = 0; ! 111: pPCXHeader->XMax = ScreenBMP.InfoHeader.biWidth-1; ! 112: pPCXHeader->YMax = abs(-ScreenBMP.InfoHeader.biHeight)-1; ! 113: pPCXHeader->NumPlanes = 3; // 24-bit ! 114: pPCXHeader->BytesPerLine = nBytesPerLine = (ScreenBMP.InfoHeader.biWidth+1)&0xfffffffe; ! 115: pPCXHeader->PaletteInfo = 1; ! 116: ! 117: // Compress picture ! 118: for(y=0; y<abs(ScreenBMP.InfoHeader.biHeight); y++) { ! 119: // Get pointer into our 16-bit screen ! 120: pSrcImage = (unsigned short int *)pScreenBitmap; ! 121: pSrcImage += ScreenBMP.InfoHeader.biWidth*y; ! 122: ! 123: // Convert to 24-bit RGB ! 124: pWorkRGBLine_Red = pSingleRGBLine; ! 125: pWorkRGBLine_Green = pWorkRGBLine_Red+nBytesPerLine; ! 126: pWorkRGBLine_Blue = pWorkRGBLine_Green+nBytesPerLine; ! 127: for(x=0; x<ScreenBMP.InfoHeader.biWidth; x++) { ! 128: // Read 16-bit pixel, as RGB 0x1555 ! 129: Pixel = *pSrcImage++; ! 130: // Split into Red,Green,Blue(range 0...255) ! 131: Red = ((Pixel>>10)&0x1f)<<3; ! 132: Green = ((Pixel>>5)&0x1f)<<3; ! 133: Blue = (Pixel&0x1f)<<3; ! 134: // And store as Red Plane, Green Plane and Blue Plane ! 135: *pWorkRGBLine_Red++ = Red; ! 136: *pWorkRGBLine_Green++ = Green; ! 137: *pWorkRGBLine_Blue++ = Blue; ! 138: } ! 139: ! 140: // Compress each of the 3 planes ! 141: pCompressedData = PCX_CompressPlanes(pSingleRGBLine,pCompressedData,nBytesPerLine*3); ! 142: } ! 143: ! 144: // And save ! 145: File_Save(NULL,pszFileName,pCompressedPCX,pCompressedData-pCompressedPCX,FALSE); ! 146: ! 147: // Free workspace ! 148: Memory_Free(pCompressedPCX); ! 149: Memory_Free(pSingleRGBLine); ! 150: */ ! 151: ! 152: } ! 153: ! 154: //----------------------------------------------------------------------- ! 155: /* ! 156: Save screen shot as .PCX using monochrome 1-bit(2 colours) ! 157: */ ! 158: void PCX_SaveScreenShot_Mono(char *pszFileName) ! 159: { ! 160: /* FIXME */ ! 161: /* ! 162: PCXHEADER *pPCXHeader; ! 163: unsigned char *pSrcImage; ! 164: unsigned char *pSingleLine; ! 165: unsigned char *pCompressedPCX, *pCompressedData; ! 166: int x,y,nBytesPerLine; ! 167: ! 168: // Allocate workspace for compression, over-estimate for compressed data ! 169: pSingleLine = (unsigned char *)Memory_Alloc(1024*2); ! 170: pCompressedData = pCompressedPCX = (unsigned char *)Memory_Alloc((ScreenBMP.InfoHeader.biWidth/3*abs(ScreenBMP.InfoHeader.biHeight))*2); ! 171: ! 172: // Create our PCX header ! 173: pPCXHeader = (PCXHEADER *)pCompressedData; ! 174: pCompressedData += sizeof(PCXHEADER); ! 175: Memory_Clear(pPCXHeader,sizeof(PCXHEADER)); ! 176: pPCXHeader->Manufact = 10; // ZSoft PCX ! 177: pPCXHeader->Version = 0; ! 178: pPCXHeader->Encoded = 1; // RLE encoding ! 179: pPCXHeader->BitsPerPixel = 1; ! 180: pPCXHeader->XMin = 0; ! 181: pPCXHeader->YMin = 0; ! 182: pPCXHeader->XMax = ScreenBMP.InfoHeader.biWidth-1; ! 183: pPCXHeader->YMax = abs(-ScreenBMP.InfoHeader.biHeight)-1; ! 184: pPCXHeader->NumPlanes = 1; // 1-bit ! 185: pPCXHeader->BytesPerLine = nBytesPerLine = ScreenBMP.InfoHeader.biWidth/8; ! 186: pPCXHeader->PaletteInfo = 0; ! 187: ! 188: // Compress picture ! 189: for(y=0; y<abs(ScreenBMP.InfoHeader.biHeight); y++) { ! 190: // Get pointer into our 1-bit screen ! 191: pSrcImage = (unsigned char *)pScreenBitmap; ! 192: pSrcImage += (ScreenBMP.InfoHeader.biWidth/8)*y; ! 193: ! 194: // Copy to line buffer and NOT to swap black/white ! 195: for(x=0; x<ScreenBMP.InfoHeader.biWidth/8; x++) { ! 196: pSingleLine[x] = ~(*pSrcImage++); ! 197: } ! 198: ! 199: // Compress it ! 200: pCompressedData = PCX_CompressPlanes(pSingleLine,pCompressedData,nBytesPerLine); ! 201: } ! 202: ! 203: // And save ! 204: File_Save(NULL,pszFileName,pCompressedPCX,pCompressedData-pCompressedPCX,FALSE); ! 205: ! 206: // Free workspace ! 207: Memory_Free(pCompressedPCX); ! 208: Memory_Free(pSingleLine); ! 209: */ ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.