Blame converter/other/pnmtopalm/palmcolormap.c

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