/* See LICENSE file for licensing information.
*/
#include "pm_c_util.h"
#include "mallocvar.h"
#include "pnm.h"
#include "palm.h"
#include "palmcolormap.h"
static pixval
scaleSample(pixval const arg,
pixval const oldMaxval,
pixval const newMaxval) {
return (arg * newMaxval + oldMaxval/2) / oldMaxval;
}
ColormapEntry
palmcolor_mapEntryColorFmPixel(pixel const color,
pixval const maxval,
pixval const newMaxval) {
return
0
| (scaleSample(PPM_GETR(color), maxval, newMaxval) << 16)
| (scaleSample(PPM_GETG(color), maxval, newMaxval) << 8)
| (scaleSample(PPM_GETB(color), maxval, newMaxval) << 0);
}
int
palmcolor_compare_indices(const void * const p1,
const void * const p2) {
/*----------------------------------------------------------------------------
This is a 'qsort' collation function.
-----------------------------------------------------------------------------*/
if ((*((ColormapEntry *) p1) & 0xFF000000) < (*((ColormapEntry *) p2) & 0xFF000000))
return -1;
else if ((*((ColormapEntry *) p1) & 0xFF000000) > (*((ColormapEntry *) p2) & 0xFF000000))
return 1;
else
return 0;
}
int
palmcolor_compare_colors(const void * const p1,
const void * const p2) {
/*----------------------------------------------------------------------------
This is a 'qsort' collation function.
-----------------------------------------------------------------------------*/
unsigned long const val1 = *((const unsigned long *) p1) & 0xFFFFFF;
unsigned long const val2 = *((const unsigned long *) p2) & 0xFFFFFF;
if (val1 < val2)
return -1;
else if (val1 > val2)
return 1;
else
return 0;
}
/***********************************************************************
***********************************************************************
***********************************************************************
******* colortables from pilrc-2.6/bitmap.c ***************************
***********************************************************************
***********************************************************************
***********************************************************************/
#if 0
/*
* The 1bit-2 color system palette for Palm Computing Devices.
*/
static int PalmPalette1bpp[2][3] =
{
{ 255, 255, 255}, { 0, 0, 0 }
};
/*
* The 2bit-4 color system palette for Palm Computing Devices.
*/
static int PalmPalette2bpp[4][3] =
{
{ 255, 255, 255}, { 192, 192, 192}, { 128, 128, 128 }, { 0, 0, 0 }
};
/*
* The 4bit-16 color system palette for Palm Computing Devices.
*/
static int PalmPalette4bpp[16][3] =
{
{ 255, 255, 255}, { 238, 238, 238 }, { 221, 221, 221 }, { 204, 204, 204 },
{ 187, 187, 187}, { 170, 170, 170 }, { 153, 153, 153 }, { 136, 136, 136 },
{ 119, 119, 119}, { 102, 102, 102 }, { 85, 85, 85 }, { 68, 68, 68 },
{ 51, 51, 51}, { 34, 34, 34 }, { 17, 17, 17 }, { 0, 0, 0 }
};
/*
* The 4bit-16 color system palette for Palm Computing Devices.
*/
static int PalmPalette4bppColor[16][3] =
{
{ 255, 255, 255}, { 128, 128, 128 }, { 128, 0, 0 }, { 128, 128, 0 },
{ 0, 128, 0}, { 0, 128, 128 }, { 0, 0, 128 }, { 128, 0, 128 },
{ 255, 0, 255}, { 192, 192, 192 }, { 255, 0, 0 }, { 255, 255, 0 },
{ 0, 255, 0}, { 0, 255, 255 }, { 0, 0, 255 }, { 0, 0, 0 }
};
#endif /* 0 */
/*
* The 8bit-256 color system palette for Palm Computing Devices.
*
* NOTE: only the first 231, plus the last one, are valid.
*/
static int PalmPalette8bpp[256][3] =
{
{ 255, 255, 255 }, { 255, 204, 255 }, { 255, 153, 255 }, { 255, 102, 255 },
{ 255, 51, 255 }, { 255, 0, 255 }, { 255, 255, 204 }, { 255, 204, 204 },
{ 255, 153, 204 }, { 255, 102, 204 }, { 255, 51, 204 }, { 255, 0, 204 },
{ 255, 255, 153 }, { 255, 204, 153 }, { 255, 153, 153 }, { 255, 102, 153 },
{ 255, 51, 153 }, { 255, 0, 153 }, { 204, 255, 255 }, { 204, 204, 255 },
{ 204, 153, 255 }, { 204, 102, 255 }, { 204, 51, 255 }, { 204, 0, 255 },
{ 204, 255, 204 }, { 204, 204, 204 }, { 204, 153, 204 }, { 204, 102, 204 },
{ 204, 51, 204 }, { 204, 0, 204 }, { 204, 255, 153 }, { 204, 204, 153 },
{ 204, 153, 153 }, { 204, 102, 153 }, { 204, 51, 153 }, { 204, 0, 153 },
{ 153, 255, 255 }, { 153, 204, 255 }, { 153, 153, 255 }, { 153, 102, 255 },
{ 153, 51, 255 }, { 153, 0, 255 }, { 153, 255, 204 }, { 153, 204, 204 },
{ 153, 153, 204 }, { 153, 102, 204 }, { 153, 51, 204 }, { 153, 0, 204 },
{ 153, 255, 153 }, { 153, 204, 153 }, { 153, 153, 153 }, { 153, 102, 153 },
{ 153, 51, 153 }, { 153, 0, 153 }, { 102, 255, 255 }, { 102, 204, 255 },
{ 102, 153, 255 }, { 102, 102, 255 }, { 102, 51, 255 }, { 102, 0, 255 },
{ 102, 255, 204 }, { 102, 204, 204 }, { 102, 153, 204 }, { 102, 102, 204 },
{ 102, 51, 204 }, { 102, 0, 204 }, { 102, 255, 153 }, { 102, 204, 153 },
{ 102, 153, 153 }, { 102, 102, 153 }, { 102, 51, 153 }, { 102, 0, 153 },
{ 51, 255, 255 }, { 51, 204, 255 }, { 51, 153, 255 }, { 51, 102, 255 },
{ 51, 51, 255 }, { 51, 0, 255 }, { 51, 255, 204 }, { 51, 204, 204 },
{ 51, 153, 204 }, { 51, 102, 204 }, { 51, 51, 204 }, { 51, 0, 204 },
{ 51, 255, 153 }, { 51, 204, 153 }, { 51, 153, 153 }, { 51, 102, 153 },
{ 51, 51, 153 }, { 51, 0, 153 }, { 0, 255, 255 }, { 0, 204, 255 },
{ 0, 153, 255 }, { 0, 102, 255 }, { 0, 51, 255 }, { 0, 0, 255 },
{ 0, 255, 204 }, { 0, 204, 204 }, { 0, 153, 204 }, { 0, 102, 204 },
{ 0, 51, 204 }, { 0, 0, 204 }, { 0, 255, 153 }, { 0, 204, 153 },
{ 0, 153, 153 }, { 0, 102, 153 }, { 0, 51, 153 }, { 0, 0, 153 },
{ 255, 255, 102 }, { 255, 204, 102 }, { 255, 153, 102 }, { 255, 102, 102 },
{ 255, 51, 102 }, { 255, 0, 102 }, { 255, 255, 51 }, { 255, 204, 51 },
{ 255, 153, 51 }, { 255, 102, 51 }, { 255, 51, 51 }, { 255, 0, 51 },
{ 255, 255, 0 }, { 255, 204, 0 }, { 255, 153, 0 }, { 255, 102, 0 },
{ 255, 51, 0 }, { 255, 0, 0 }, { 204, 255, 102 }, { 204, 204, 102 },
{ 204, 153, 102 }, { 204, 102, 102 }, { 204, 51, 102 }, { 204, 0, 102 },
{ 204, 255, 51 }, { 204, 204, 51 }, { 204, 153, 51 }, { 204, 102, 51 },
{ 204, 51, 51 }, { 204, 0, 51 }, { 204, 255, 0 }, { 204, 204, 0 },
{ 204, 153, 0 }, { 204, 102, 0 }, { 204, 51, 0 }, { 204, 0, 0 },
{ 153, 255, 102 }, { 153, 204, 102 }, { 153, 153, 102 }, { 153, 102, 102 },
{ 153, 51, 102 }, { 153, 0, 102 }, { 153, 255, 51 }, { 153, 204, 51 },
{ 153, 153, 51 }, { 153, 102, 51 }, { 153, 51, 51 }, { 153, 0, 51 },
{ 153, 255, 0 }, { 153, 204, 0 }, { 153, 153, 0 }, { 153, 102, 0 },
{ 153, 51, 0 }, { 153, 0, 0 }, { 102, 255, 102 }, { 102, 204, 102 },
{ 102, 153, 102 }, { 102, 102, 102 }, { 102, 51, 102 }, { 102, 0, 102 },
{ 102, 255, 51 }, { 102, 204, 51 }, { 102, 153, 51 }, { 102, 102, 51 },
{ 102, 51, 51 }, { 102, 0, 51 }, { 102, 255, 0 }, { 102, 204, 0 },
{ 102, 153, 0 }, { 102, 102, 0 }, { 102, 51, 0 }, { 102, 0, 0 },
{ 51, 255, 102 }, { 51, 204, 102 }, { 51, 153, 102 }, { 51, 102, 102 },
{ 51, 51, 102 }, { 51, 0, 102 }, { 51, 255, 51 }, { 51, 204, 51 },
{ 51, 153, 51 }, { 51, 102, 51 }, { 51, 51, 51 }, { 51, 0, 51 },
{ 51, 255, 0 }, { 51, 204, 0 }, { 51, 153, 0 }, { 51, 102, 0 },
{ 51, 51, 0 }, { 51, 0, 0 }, { 0, 255, 102 }, { 0, 204, 102 },
{ 0, 153, 102 }, { 0, 102, 102 }, { 0, 51, 102 }, { 0, 0, 102 },
{ 0, 255, 51 }, { 0, 204, 51 }, { 0, 153, 51 }, { 0, 102, 51 },
{ 0, 51, 51 }, { 0, 0, 51 }, { 0, 255, 0 }, { 0, 204, 0 },
{ 0, 153, 0 }, { 0, 102, 0 }, { 0, 51, 0 }, { 17, 17, 17 },
{ 34, 34, 34 }, { 68, 68, 68 }, { 85, 85, 85 }, { 119, 119, 119 },
{ 136, 136, 136 }, { 170, 170, 170 }, { 187, 187, 187 }, { 221, 221, 221 },
{ 238, 238, 238 }, { 192, 192, 192 }, { 128, 0, 0 }, { 128, 0, 128 },
{ 0, 128, 0 }, { 0, 128, 128 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
};
Colormap *
palmcolor_build_default_8bit_colormap(void) {
unsigned int i;
Colormap * cmP;
MALLOCVAR_NOFAIL(cmP);
cmP->nentries = 232;
MALLOCARRAY_NOFAIL(cmP->color_entries, cmP->nentries);
/* Fill in the colors */
for (i = 0; i < 231; ++i) {
cmP->color_entries[i] = ((i << 24) |
(PalmPalette8bpp[i][0] << 16) |
(PalmPalette8bpp[i][1] << 8) |
(PalmPalette8bpp[i][2]));
}
cmP->color_entries[231] = 0xFF000000;
cmP->ncolors = 232;
/* now sort the table */
qsort(cmP->color_entries, cmP->ncolors, sizeof(ColormapEntry),
palmcolor_compare_colors);
return cmP;
}
Colormap *
palmcolor_build_custom_8bit_colormap(pixel ** const pixels,
unsigned int const rows,
unsigned int const cols,
pixval const maxval) {
unsigned int row;
Colormap * colormapP;
MALLOCVAR_NOFAIL(colormapP);
colormapP->nentries = 256;
MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries);
colormapP->ncolors = 0; /* initial value */
for (row = 0; row < rows; ++row) {
unsigned int col;
for (col = 0; col < cols; ++col) {
ColormapEntry * foundEntryP;
ColormapEntry const searchTarget =
palmcolor_mapEntryColorFmPixel(pixels[row][col], maxval, 255);
foundEntryP =
bsearch(&searchTarget,
colormapP->color_entries, colormapP->ncolors,
sizeof(ColormapEntry), palmcolor_compare_colors);
if (!foundEntryP) {
if (colormapP->ncolors >= colormapP->nentries)
pm_error("Too many colors for custom colormap "
"(max %u). "
"Try using pnmquant to reduce the number "
"of colors.", colormapP->nentries);
else {
/* add the new color, and re-sort */
unsigned int const colorIndex = colormapP->ncolors++;
ColormapEntry const newEntry =
searchTarget | (colorIndex << 24);
colormapP->color_entries[colorIndex] = newEntry;
qsort(colormapP->color_entries, colormapP->ncolors,
sizeof(ColormapEntry), palmcolor_compare_colors);
}
}
}
}
return colormapP;
}
Colormap *
palmcolor_read_colormap (FILE * const ifP) {
unsigned short ncolors;
Colormap * retval;
int rc;
rc = pm_readbigshort(ifP, (short *) &ncolors);
if (rc != 0)
retval = NULL;
else {
long colorentry;
Colormap * colormapP;
unsigned int i;
bool error;
MALLOCVAR_NOFAIL(colormapP);
colormapP->nentries = ncolors;
MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries);
for (i = 0, error = FALSE; i < ncolors && !error; ++i) {
int rc;
rc = pm_readbiglong(ifP, &colorentry);
if (rc != 0)
error = TRUE;
else
colormapP->color_entries[i] = (colorentry & 0xFFFFFFFF);
}
if (error) {
free (colormapP->color_entries);
free (colormapP);
retval = NULL;
} else {
colormapP->ncolors = ncolors;
retval = colormapP;
}
}
return retval;
}