131 lines
3.3 KiB
C
131 lines
3.3 KiB
C
/*
|
|
PAL 2 COLORMAP SOURCECODE
|
|
|
|
The MIT License (MIT)
|
|
|
|
Copyright (c) 2016-2019 Marco "eukara" Hladik <marco at icculus.org>
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <stdlib.h>
|
|
|
|
#define TGAHEADER 18
|
|
#define QPALSIZE 768
|
|
#define QCOLORSIZE 16384
|
|
|
|
/* sample a 24-bit RGB value to one of the colours on the existing 8-bit palette */
|
|
unsigned char
|
|
convert_24_to_8 (const unsigned char palette[768], const int rgb[3])
|
|
{
|
|
int i, j;
|
|
int best_index = -1;
|
|
int best_dist = 0;
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
int dist = 0;
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
/* note that we could use RGB luminosity bias for greater accuracy, but quake's colormap apparently didn't do this */
|
|
int d = abs(rgb[j] - palette[i * 3 + j]);
|
|
dist += d * d;
|
|
}
|
|
|
|
if (best_index == -1 || dist < best_dist) {
|
|
best_index = i;
|
|
best_dist = dist;
|
|
}
|
|
}
|
|
|
|
return (unsigned char) best_index;
|
|
}
|
|
|
|
void
|
|
process_pal2colormap(char *filename)
|
|
{
|
|
FILE *fLMP;
|
|
unsigned char pal_buff[QPALSIZE];
|
|
FILE *fTGA;
|
|
unsigned char colormap_buff[QCOLORSIZE];
|
|
short pal_loop, tga_loop;
|
|
struct stat pal_st;
|
|
int num_fullbrights = 0; /* the last 32 colours will be full bright */
|
|
int x, y, i;
|
|
|
|
fLMP = fopen(filename, "rb");
|
|
|
|
if (!fLMP) {
|
|
fprintf(stderr, "couldn't find %s\n", filename);
|
|
return;
|
|
}
|
|
|
|
/* There are no other types of palette lumps. Sorry */
|
|
stat(filename, &pal_st);
|
|
if (pal_st.st_size != QPALSIZE) {
|
|
fprintf(stderr, "invalid palette lump %s, skipping\n", filename);
|
|
return;
|
|
}
|
|
|
|
fread(pal_buff, 1, QPALSIZE, fLMP);
|
|
fclose(fLMP);
|
|
|
|
for ( x = 0; x < 256; x++ ) {
|
|
for ( y = 0; y < 64; y++ ) {
|
|
if ( x < 256 - num_fullbrights ) {
|
|
int rgb[3];
|
|
|
|
for ( i = 0; i < 3; i++ ) {
|
|
/* divide by 32, rounding to nearest integer */
|
|
rgb[i] = ( pal_buff[x * 3 + i] * ( 63 - y ) + 16 ) >> 5;
|
|
if ( rgb[i] > 255 )
|
|
rgb[i] = 255;
|
|
}
|
|
|
|
colormap_buff[y * 256 + x] = convert_24_to_8( pal_buff, rgb );
|
|
} else {
|
|
/* this colour is a fullbright, just keep the original colour */
|
|
colormap_buff[y * 256 + x] = x;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
fTGA = fopen("colormap.lmp", "w+b");
|
|
fwrite(colormap_buff, 1, QCOLORSIZE, fTGA);
|
|
fclose(fTGA);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
int c;
|
|
|
|
if (argc <= 1) {
|
|
fprintf(stderr, "usage: pal2colormap [file.lmp ...]\n");
|
|
return 1;
|
|
}
|
|
|
|
for (c = 1; c < argc; c++)
|
|
process_pal2colormap(argv[c]);
|
|
|
|
return 0;
|
|
}
|