18 assert(filename !=
nullptr);
19 assert(filename[0] !=
'\0');
21 std::ifstream file(filename, std::ios::in | std::ios::binary);
24 unsigned char* header =
new unsigned char[128];
27 if (!file.read((
char*)(&header[0]), 128)) {
33 if (header[0] != 0x0A) {
34 Log::get(
LOG_ERROR) <<
"Magic number at file start is wrong (" << header[0] <<
" != 0x0A)" <<
40 if ((header[1] != 0) && ((header[1] < 2) || (header[1] > 5))) {
47 if ((header[2] != 0) && (header[2] != 1)) {
59 if (header[64] != 0) {
69 int pcxLoad(
const char* filename,
unsigned char** image,
70 unsigned int* width,
unsigned int* height,
72 assert(filename !=
nullptr);
73 assert(filename[0] !=
'\0');
80 std::ifstream file(filename, std::ios::in | std::ios::binary);
83 unsigned char* header =
new unsigned char[128];
86 if (!file.read((
char*)(&header[0]), 128)) {
92 if (header[0] != 0x0A) {
93 Log::get(
LOG_ERROR) <<
"Magic number at file start is wrong (" << header[0] <<
" != 0x0A)" <<
99 if ((header[1] != 0) && ((header[1] < 2) || (header[1] > 5))) {
106 if ((header[2] != 0) && (header[2] != 1)) {
112 if (header[3] != 8) {
118 if (header[64] != 0) {
125 bool versionFive = (header[1] == 5);
126 bool compressed = (header[2] == 1);
128 unsigned int xMin = header[4] | (header[5] << 8);
129 unsigned int yMin = header[6] | (header[7] << 8);
130 unsigned int xMax = header[8] | (header[9] << 8);
131 unsigned int yMax = header[10] | (header[11] << 8);
135 unsigned char nPlanes = header[65];
136 unsigned int bytesPerLine = header[66] | (header[67] << 8);
144 *width = xMax - xMin + 1;
145 *height = yMax - yMin + 1;
146 unsigned long totalBytes = nPlanes * bytesPerLine;
147 unsigned long imageSize = totalBytes** height;
148 unsigned char* buffer =
new unsigned char[imageSize];
152 for (
unsigned long i = 0; i < imageSize;) {
157 << (file.eof() ?
" EOF" :
"") <<
")" <<
Log::endl;
164 if ((c & 0xC0) == 0xC0) {
169 << (file.eof() ?
" EOF" :
"") <<
")" <<
Log::endl;
176 for (
unsigned int j = 0; j < n; j++)
177 buffer[b++] = (
unsigned char)c;
183 unsigned char* palette =
nullptr;
186 if ((c == 12) && file) {
187 palette =
new unsigned char[768];
188 for (
unsigned int i = 0; i < 768; i++) {
189 palette[i] = (
unsigned char)file.get();
201 unsigned long size = *width** height * 4;
202 *image =
new unsigned char[size];
203 for (
unsigned int y = 0; y < *height; y++) {
204 for (
unsigned int x = 0; x < *width; x++) {
205 unsigned long baseIndex = (x + (y** width)) * 4;
206 unsigned char alpha = 255, red = 0, green = 0, blue = 0;
208 if (palette !=
nullptr) {
210 red = palette[buffer[(y * totalBytes) + x] * 3];
211 green = palette[(buffer[(y * totalBytes) + x] * 3) + 1];
212 blue = palette[(buffer[(y * totalBytes) + x] * 3) + 2];
222 if ((nPlanes == 3) || (nPlanes == 4)) {
223 red = buffer[(y * totalBytes) + x];
224 green = buffer[(y * totalBytes) + *width + x];
225 blue = buffer[(y * totalBytes) + (2 * *width) + x];
227 alpha = buffer[(y * totalBytes) + (3 * *width) + x];
228 }
else if (nPlanes == 1) {
229 red = green = blue = buffer[(y * totalBytes) + x];
240 (*image)[baseIndex + 0] = red;
241 (*image)[baseIndex + 1] = green;
242 (*image)[baseIndex + 2] = blue;
243 (*image)[baseIndex + 3] = alpha;
int pcxCheck(const char *filename)
Check if a file is a valid PCX image.
static LogLevel & get(int level)
int pcxLoad(const char *filename, unsigned char **image, unsigned int *width, unsigned int *height, ColorMode *mode, unsigned int *bpp)
Load a PCX image file into a buffer.