|
|
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.