242 lines
7.4 KiB
C
242 lines
7.4 KiB
C
|
/****************************************************************************
|
||
|
* apps/graphics/traveler/tools/libwld/wld_loadpaltable.c
|
||
|
* This file contains the logic that creates the range palette table that is
|
||
|
* used to modify the palette with range to hit
|
||
|
*
|
||
|
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
*
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in
|
||
|
* the documentation and/or other materials provided with the
|
||
|
* distribution.
|
||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||
|
* used to endorse or promote products derived from this software
|
||
|
* without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
/*************************************************************************
|
||
|
* Included files
|
||
|
*************************************************************************/
|
||
|
|
||
|
#include "trv_types.h"
|
||
|
#include "wld_bitmaps.h"
|
||
|
#include "wld_color.h"
|
||
|
|
||
|
/****************************************************************************
|
||
|
* Name: wld_lum2formtype
|
||
|
*
|
||
|
* Description:
|
||
|
* Convert an ordered RGB-Luminance value a color form (index into
|
||
|
* XXXForm arrays).
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#if RGB_CUBE_SIZE < MIN_LUM_LEVELS
|
||
|
static uint8_t wld_lum2formtype(color_form_t *lum)
|
||
|
{
|
||
|
float factor1;
|
||
|
float factor2;
|
||
|
float factor3;
|
||
|
float error;
|
||
|
float lse;
|
||
|
uint8_t formno;
|
||
|
int i;
|
||
|
|
||
|
/* Initialize for the search */
|
||
|
|
||
|
factor1 = g_wld_colorform[0].max - lum->max;
|
||
|
factor2 = g_wld_colorform[0].mid - lum->mid;
|
||
|
factor3 = g_wld_colorform[0].min - lum->min;
|
||
|
lse = factor1*factor1 + factor2*factor2 + factor3*factor3;
|
||
|
formno = 0;
|
||
|
|
||
|
/* Now, search the rest of the table, keeping the form with least
|
||
|
* squared error value
|
||
|
*/
|
||
|
|
||
|
for (i = 1; i < NCOLOR_FORMS; i++)
|
||
|
{
|
||
|
factor1 = g_wld_colorform[i].max - lum->max;
|
||
|
factor2 = g_wld_colorform[i].mid - lum->mid;
|
||
|
factor3 = g_wld_colorform[i].min - lum->min;
|
||
|
error = factor1*factor1 + factor2*factor2 + factor3*factor3;
|
||
|
if (error < lse)
|
||
|
{
|
||
|
lse = error;
|
||
|
formno = i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return formno;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/****************************************************************************
|
||
|
* Name: wld_lum2colorform
|
||
|
*
|
||
|
* Description:
|
||
|
* Convert an RGB-Luminance value into a color form code (index into
|
||
|
* g_unit_vector array).
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#if RGB_CUBE_SIZE < MIN_LUM_LEVELS
|
||
|
static enum unit_vector_index_e wld_lum2colorform(color_lum_t *lum)
|
||
|
{
|
||
|
color_form_t orderedLum;
|
||
|
enum unit_vector_index_e uvndx;
|
||
|
|
||
|
/* Get an ordered representation of the luminance value */
|
||
|
|
||
|
if (lum->red >= lum->green)
|
||
|
{
|
||
|
if (lum->red >= lum->blue)
|
||
|
{
|
||
|
/* RED >= GREEN && RED >= BLUE */
|
||
|
|
||
|
if (lum->green >= lum->blue)
|
||
|
{
|
||
|
/* RED >= GREEN >= BLUE */
|
||
|
|
||
|
orderedLum.max = lum->red;
|
||
|
orderedLum.mid = lum->green;
|
||
|
orderedLum.min = lum->blue;
|
||
|
uvndx = g_wld_rgbform_map[wld_lum2formtype(&orderedLum)];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* RED >= BLUE > GREEN */
|
||
|
|
||
|
orderedLum.max = lum->red;
|
||
|
orderedLum.mid = lum->blue;
|
||
|
orderedLum.min = lum->green;
|
||
|
uvndx = g_wld_rbgform_map[wld_lum2formtype(&orderedLum)];
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* BLUE > RED >= GREEN */
|
||
|
|
||
|
orderedLum.max = lum->blue;
|
||
|
orderedLum.mid = lum->red;
|
||
|
orderedLum.min = lum->green;
|
||
|
uvndx = g_wld_brgform_map[wld_lum2formtype(&orderedLum)];
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* lum->red < lum->green) */
|
||
|
|
||
|
if (lum->green >= lum->blue)
|
||
|
{
|
||
|
/* GREEN > RED && GREEN >= BLUE */
|
||
|
|
||
|
if (lum->red >= lum->blue)
|
||
|
{
|
||
|
/* GREEN > RED >= BLUE */
|
||
|
|
||
|
orderedLum.max = lum->green;
|
||
|
orderedLum.mid = lum->red;
|
||
|
orderedLum.min = lum->blue;
|
||
|
uvndx = g_wld_grbform_map[wld_lum2formtype(&orderedLum)];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* GREEN >= BLUE > RED*/
|
||
|
|
||
|
orderedLum.max = lum->green;
|
||
|
orderedLum.mid = lum->blue;
|
||
|
orderedLum.min = lum->red;
|
||
|
uvndx = g_wld_gbrform_map[wld_lum2formtype(&orderedLum)];
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* BLUE > GREEN > RED */
|
||
|
|
||
|
orderedLum.max = lum->blue;
|
||
|
orderedLum.mid = lum->green;
|
||
|
orderedLum.min = lum->red;
|
||
|
uvndx = g_wld_bgrform_map[wld_lum2formtype(&orderedLum)];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return uvndx;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/****************************************************************************
|
||
|
* Name: wld_color_lum2pixel
|
||
|
* Description: Convert an RGB-Luminance value into a pixel
|
||
|
****************************************************************************/
|
||
|
|
||
|
wld_pixel_t wld_color_lum2pixel(color_lum_t *lum)
|
||
|
{
|
||
|
#if RGB_CUBE_SIZE < MIN_LUM_LEVELS
|
||
|
enum unit_vector_index_e uvndx;
|
||
|
uint8_t lumndx;
|
||
|
|
||
|
/* Get the g_unit_vector array index associated with this lum */
|
||
|
|
||
|
uvndx = wld_lum2colorform(lum);
|
||
|
|
||
|
/* Get the luminance number associated with this lum at this index
|
||
|
* Make sure that the requested luminance does not exceed the maximum
|
||
|
* allowed for this unit vector.
|
||
|
*/
|
||
|
|
||
|
if (lum->luminance >= g_unit_vector[uvndx].luminance)
|
||
|
{
|
||
|
lumndx = (NLUMINANCES-1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lumndx = (uint8_t)((float)NLUMINANCES
|
||
|
* lum->luminance / g_unit_vector[uvndx].luminance);
|
||
|
if (lumndx > 0)
|
||
|
{
|
||
|
lumndx--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Now get the pixel value from the unit vector index and the luminance
|
||
|
* number. We will probably have to expand this later from the 8-bit
|
||
|
* index to a wider representation.
|
||
|
*/
|
||
|
|
||
|
return TRV_UVLUM2NDX(uvndx, lumndx);
|
||
|
|
||
|
#else
|
||
|
color_rgb_t rgb;
|
||
|
|
||
|
/* Convert the luminance value to its RGB components */
|
||
|
|
||
|
rgb.red = lum->red * lum->luminance;
|
||
|
rgb.green = lum->green * lum->luminance;
|
||
|
rgb.blue = lum->blue * lum->luminance;
|
||
|
|
||
|
return wld_rgb2pixel(&rgb);
|
||
|
#endif
|
||
|
}
|