242 lines
7.3 KiB
C
242 lines
7.3 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_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 WLD_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
|
|
}
|