1 namespace gfx::bitmaps;
16 uint16 xMin,yMin __attribute__((packed));
17 uint16 xMax,yMax __attribute__((packed));
18 uint16 hRes __attribute__((packed));
19 uint16 vRes __attribute__((packed));
23 uint16 bytesPerLine __attribute__((packed));
24 uint16 paletteType __attribute__((packed));
30 static char * extensions[] = { "pcx", null };
32 class PCXFormat : BitmapFormat
34 class_property(extensions) = extensions;
36 bool Load(Bitmap bitmap, File f)
41 if(f.Read(&header,sizeof(header),1))
43 if(header.xMax > header.xMin && header.yMax > header.yMin)
45 switch(header.colorPlanes)
48 result = bitmap.Allocate(null,
49 header.xMax-header.xMin+1,header.yMax-header.yMin+1,
50 header.xMax-header.xMin+1, pixelFormat8, true);
53 result = bitmap.Allocate(null,
54 header.xMax-header.xMin+1,header.yMax-header.yMin+1,
55 header.xMax-header.xMin+1, pixelFormat888, false);
61 byte b = 0, count = 0;
64 uint iptr=0, y = 0, x = 0;
66 uint16 colorPlane = 0;
72 for(; y <= header.yMax; )
76 if(!f.Read(buf, 1, BUFLEN)) break;
87 if(!f.Read(buf, 1, BUFLEN)) break;
96 if(bitmap.pixelFormat == pixelFormat888)
98 iptr = (y*bitmap.width) + x;
99 if(x <= header.xMax && y <= header.yMax)
104 ((RGBA32*)bitmap.picture)[iptr].a = 255;
105 ((RGBA32*)bitmap.picture)[iptr].r = b;
107 case 1: ((RGBA32*)bitmap.picture)[iptr].g = b; break;
108 case 2: ((RGBA32*)bitmap.picture)[iptr].b = b; break;
112 if(x == header.bytesPerLine)
123 else if(bitmap.pixelFormat == pixelFormat8)
125 if(x <= header.xMax && y <= header.yMax)
126 bitmap.picture[iptr] = b;
129 if(x == header.bytesPerLine)
131 iptr+= bitmap.stride - x;
139 if(bitmap.pixelFormat == pixelFormat8)
144 if(f.Read(palette, 768, 1))
147 bitmap.palette[c] = ColorAlpha { 255, { palette[c*3], palette[c*3+1], palette[c*3+2] } };
161 bool Save(Bitmap bitmap, char *filename, void * options)
164 if(bitmap.pixelFormat == pixelFormat8 || bitmap.pixelFormat == pixelFormat888)
166 File f = FileOpen(filename, write);
170 int div = (bitmap.pixelFormat == pixelFormat8) ? (bitmap.width % 2) : 0;
174 header.manufacturer=10;
177 header.bitsPerPixel=8;
180 header.xMax=(uint16)(bitmap.width-1);
181 header.yMax=(uint16)(bitmap.height-1);
184 FillBytes(header.palette16, 0, 48);
186 if(bitmap.pixelFormat == pixelFormat8)
187 header.colorPlanes = 1;
188 else if(bitmap.pixelFormat == pixelFormat888)
189 header.colorPlanes=3;
190 header.bytesPerLine=(uint16)(bitmap.width+div);
191 header.paletteType=1;
192 FillBytes(header.filler, 0, 58);
194 if(f.Write(&header, sizeof(header), 1))
202 uint16 colorPlane = 0;
205 bool errorWriting = false;
207 padder = (bitmap.pixelFormat == pixelFormat8) ? 0xFF : 0x00;
209 for(; (iptr<bitmap.size || count) && !errorWriting; )
211 iptr = (y*bitmap.stride) + x;
212 for(;iptr<bitmap.size;)
214 if(bitmap.pixelFormat == pixelFormat888)
218 case 0: b = ((RGBA32*)bitmap.picture)[iptr].r; break;
219 case 1: b = ((RGBA32*)bitmap.picture)[iptr].g; break;
220 case 2: b = ((RGBA32*)bitmap.picture)[iptr].b; break;
224 b = bitmap.picture[iptr];
239 if(bitmap.pixelFormat == pixelFormat888)
250 iptr = y*bitmap.stride;
253 if(last == padder && count <= 63-div &&
254 (colorPlane || bitmap.pixelFormat == pixelFormat8))
268 if((count>1)||(last>=192))
269 if(!f.Putc((byte)(count+192))) { errorWriting = true; break; }
270 if(!f.Putc(last)) { errorWriting = true; break; }
275 // Padding can mix with rest between 2 color planes in a scan line
276 if(colorPlane || bitmap.pixelFormat == pixelFormat8)
284 if(f.Putc((byte)(div+192))) { errorWriting = true; break; }
285 if(f.Putc(padder)) { errorWriting = true; break; }
293 if(bitmap.pixelFormat == pixelFormat8)
296 // Shift palette 2 bytes left
299 palette[c*3] = bitmap.palette[c].color.r;
300 palette[c*3+1] = bitmap.palette[c].color.g;
301 palette[c*3+2] = bitmap.palette[c].color.b;
304 if(f.Write(palette, 768, 1))
317 ColorAlpha * LoadPalette(char * fileName, char * type)
319 ColorAlpha * result = null;
320 File f = FileOpen(fileName, read);
325 if(f.Read(&header,sizeof(header),1))
327 if(header.colorPlanes == 1)
332 if(f.Read(palette, 768, 1))
334 if((result = new ColorAlpha[256]))
338 result[c] = ColorAlpha { 255, { palette[c*3], palette[c*3+1], palette[c*3+2] } };