NxWidgets::CScaledImage: New class that wraps any class that provides IBitMap and adds image scaling
This commit is contained in:
parent
b5a37a3e45
commit
24ee501467
|
@ -387,4 +387,7 @@
|
|||
* NxWM::CCalibration.cxx/hxx: Add options to collect and average
|
||||
multiple samples at each location. Also logic to discard the most
|
||||
extreme samples before averaging (2013-10-14).
|
||||
* NxWidgets::CScaledImage: This new class is a wrapper for an class
|
||||
the exports IBitMap. It will perform scaling via bi-linear interpolation
|
||||
so that images can be scaled to any size desired (2013-10-15).
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#################################################################################
|
||||
# NxWidgets/libnxwidgets/Makefile
|
||||
#
|
||||
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
@ -52,7 +52,7 @@ CXXSRCS = cbitmap.cxx cbgwindow.cxx ccallback.cxx cgraphicsport.cxx
|
|||
CXXSRCS += clistdata.cxx clistdataitem.cxx cnxfont.cxx
|
||||
CXXSRCS += cnxserver.cxx cnxstring.cxx cnxtimer.cxx cnxwidget.cxx cnxwindow.cxx
|
||||
CXXSRCS += cnxtkwindow.cxx cnxtoolbar.cxx crect.cxx crlepalettebitmap.cxx
|
||||
CXXSRCS += cstringiterator.cxx ctext.cxx cwidgetcontrol.cxx cwidgeteventhandlerlist.cxx
|
||||
CXXSRCS += cscaledbitmap.cxx cstringiterator.cxx ctext.cxx cwidgetcontrol.cxx cwidgeteventhandlerlist.cxx
|
||||
CXXSRCS += cwindoweventhandlerlist.cxx singletons.cxx
|
||||
# Widget APIs
|
||||
CXXSRCS += cbutton.cxx cbuttonarray.cxx ccheckbox.cxx ccyclebutton.cxx
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace NXWidgets
|
|||
* @return The bitmap's width.
|
||||
*/
|
||||
|
||||
const nxgl_coord_t getStride(void) const;
|
||||
const size_t getStride(void) const;
|
||||
|
||||
/**
|
||||
* Use the colors associated with a selected image.
|
||||
|
|
|
@ -235,7 +235,7 @@ namespace NXWidgets
|
|||
* @return The bitmap's width.
|
||||
*/
|
||||
|
||||
const nxgl_coord_t getStride(void) const;
|
||||
const size_t getStride(void) const;
|
||||
|
||||
/**
|
||||
* Use the colors associated with a selected image.
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
/****************************************************************************
|
||||
* NxWidgets/libnxwidgets/include/cscaledbitmap.hxx
|
||||
*
|
||||
* Copyright (C) 2013 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, NxWidgets, nor the names of its contributors
|
||||
* me 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_CSCALEDBITMAP_HXX
|
||||
#define __INCLUDE_CSCALEDBITMAP_HXX
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <fixedmath.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/rgbcolors.h>
|
||||
#include <nuttx/nx/nxglib.h>
|
||||
|
||||
#include "nxconfig.hxx"
|
||||
#include "ibitmap.hxx"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation Classes
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
namespace NXWidgets
|
||||
{
|
||||
/**
|
||||
* Class for scaling layer for any bitmap that inherits from IBitMap
|
||||
*/
|
||||
|
||||
class CScaledBitmap : public IBitmap
|
||||
{
|
||||
protected:
|
||||
FAR IBitmap *m_bitmap; /**< The bitmap that is being scaled */
|
||||
struct nxgl_size_s m_size; /**< Scaled size of the image */
|
||||
FAR uint8_t *m_rowCache[2]; /**< Two cached rows of the image */
|
||||
unsigned int m_row; /**< Row number of the first cached row */
|
||||
b16_t m_xScale; /**< X scale factor */
|
||||
b16_t m_yScale; /**< Y scale factor */
|
||||
|
||||
/**
|
||||
* Read two rows into the row cache
|
||||
*
|
||||
* @param row - The row number of the first row to cache
|
||||
*/
|
||||
|
||||
bool cacheRows(unsigned int row);
|
||||
|
||||
/**
|
||||
* Given an two RGB colors and a fractional value, return the scaled
|
||||
* value between the two colors.
|
||||
*
|
||||
* @param incolor1 - The first color to be used
|
||||
* @param incolor2 - The second color to be used
|
||||
* @param fraction - The fractional value
|
||||
* @param outcolor - The returned, scaled color
|
||||
*/
|
||||
|
||||
bool scaleColor(FAR const struct rgbcolor_s &incolor1,
|
||||
FAR const struct rgbcolor_s &incolor2,
|
||||
b16_t fraction, FAR struct rgbcolor_s &outcolor);
|
||||
|
||||
/**
|
||||
* Given an image row and a non-integer column offset, return the
|
||||
* interpolated RGB color value corresponding to that position
|
||||
*
|
||||
* @param row - The pointer to the row in the row cache to use
|
||||
* @param column - The non-integer column offset
|
||||
* @param outcolor - The returned, interpolated color
|
||||
*
|
||||
*/
|
||||
|
||||
bool rowColor(FAR uint8_t *row, b16_t column,
|
||||
FAR struct rgbcolor_s &outcolor);
|
||||
|
||||
/**
|
||||
* Copy constructor is protected to prevent usage.
|
||||
*/
|
||||
|
||||
inline CScaledBitmap(const CScaledBitmap &bitmap) { }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param bitmap The bitmap structure being scaled.
|
||||
* @newSize The new, scaled size of the image
|
||||
*/
|
||||
|
||||
CScaledBitmap(IBitmap *bitmap, struct nxgl_size_s &newSize);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
|
||||
~CScaledBitmap(void);
|
||||
|
||||
/**
|
||||
* Get the bitmap's color format.
|
||||
*
|
||||
* @return The bitmap's color format.
|
||||
*/
|
||||
|
||||
const uint8_t getColorFormat(void) const;
|
||||
|
||||
/**
|
||||
* Get the bitmap's color format.
|
||||
*
|
||||
* @return The bitmap's pixel depth.
|
||||
*/
|
||||
|
||||
const uint8_t getBitsPerPixel(void) const;
|
||||
|
||||
/**
|
||||
* Get the bitmap's width (in pixels/columns).
|
||||
*
|
||||
* @return The bitmap's width (in pixels/columns).
|
||||
*/
|
||||
|
||||
const nxgl_coord_t getWidth(void) const;
|
||||
|
||||
/**
|
||||
* Get the bitmap's height (in rows).
|
||||
*
|
||||
* @return The bitmap's height (in rows).
|
||||
*/
|
||||
|
||||
inline const nxgl_coord_t getHeight(void) const;
|
||||
|
||||
/**
|
||||
* Get the bitmap's width (in bytes).
|
||||
*
|
||||
* @return The bitmap's width (in bytes).
|
||||
*/
|
||||
|
||||
const size_t getStride(void) const;
|
||||
|
||||
/**
|
||||
* Use the colors associated with a selected image.
|
||||
*
|
||||
* @param selected. true: Use colors for a selected widget,
|
||||
* false: Use normal (default) colors.
|
||||
*/
|
||||
|
||||
inline void setSelected(bool selected) {}
|
||||
|
||||
/**
|
||||
* Get one row from the bit map image.
|
||||
*
|
||||
* @param x The offset into the row to get
|
||||
* @param y The row number to get
|
||||
* @param width The number of pixels to get from the row
|
||||
* @param data The memory location provided by the caller
|
||||
* in which to return the data. This should be at least
|
||||
* (getWidth()*getBitsPerPixl() + 7)/8 bytes in length
|
||||
* and properly aligned for the pixel color format.
|
||||
* @param True if the run was returned successfully.
|
||||
*/
|
||||
|
||||
bool getRun(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width,
|
||||
FAR void *data);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __INCLUDE_CSCALEDBITMAP_HXX
|
|
@ -73,9 +73,10 @@
|
|||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -84,11 +85,11 @@
|
|||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation Classes
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
namespace NXWidgets
|
||||
|
@ -114,7 +115,7 @@ namespace NXWidgets
|
|||
/**
|
||||
* Get the bitmap's color format.
|
||||
*
|
||||
* @return The bitmap's width.
|
||||
* @return The bitmap's color format.
|
||||
*/
|
||||
|
||||
virtual const uint8_t getColorFormat(void) const = 0;
|
||||
|
@ -130,7 +131,7 @@ namespace NXWidgets
|
|||
/**
|
||||
* Get the bitmap's width (in pixels/columns).
|
||||
*
|
||||
* @return The bitmap's pixel depth.
|
||||
* @return The bitmap's width (in pixels/columns).
|
||||
*/
|
||||
|
||||
virtual const nxgl_coord_t getWidth(void) const = 0;
|
||||
|
@ -138,7 +139,7 @@ namespace NXWidgets
|
|||
/**
|
||||
* Get the bitmap's height (in rows).
|
||||
*
|
||||
* @return The bitmap's height.
|
||||
* @return The bitmap's height (in rows).
|
||||
*/
|
||||
|
||||
virtual const nxgl_coord_t getHeight(void) const = 0;
|
||||
|
@ -149,7 +150,7 @@ namespace NXWidgets
|
|||
* @return The bitmap's width.
|
||||
*/
|
||||
|
||||
virtual const nxgl_coord_t getStride(void) const = 0;
|
||||
virtual const size_t getStride(void) const = 0;
|
||||
|
||||
/**
|
||||
* Use the colors associated with a selected image.
|
||||
|
|
|
@ -149,7 +149,7 @@ const nxgl_coord_t CBitmap::getHeight(void) const
|
|||
* @return The bitmap's width.
|
||||
*/
|
||||
|
||||
const nxgl_coord_t CBitmap::getStride(void) const
|
||||
const size_t CBitmap::getStride(void) const
|
||||
{
|
||||
return m_bitmap->stride;
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ bool CBitmap::getRun(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width,
|
|||
{
|
||||
// Check ranges. Casts to unsigned int are ugly but permit one-sided comparisons
|
||||
|
||||
if (((unsigned int)x < (unsigned int)width) &&
|
||||
if (((unsigned int)x < (unsigned int)m_bitmap->width) &&
|
||||
((unsigned int)(x + width) <= (unsigned int)m_bitmap->width) &&
|
||||
((unsigned int)y < (unsigned int)m_bitmap->height))
|
||||
{
|
||||
|
|
|
@ -155,7 +155,7 @@ const nxgl_coord_t CRlePaletteBitmap::getHeight(void) const
|
|||
* @return The bitmap's width.
|
||||
*/
|
||||
|
||||
const nxgl_coord_t CRlePaletteBitmap::getStride(void) const
|
||||
const size_t CRlePaletteBitmap::getStride(void) const
|
||||
{
|
||||
// This only works if the bpp is an even multiple of 8-bit bytes
|
||||
|
||||
|
|
|
@ -0,0 +1,583 @@
|
|||
/****************************************************************************
|
||||
* NxWidgets/libnxwidgets/src/cscaledbitmap.hxx
|
||||
*
|
||||
* Copyright (C) 2013 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, NxWidgets, nor the names of its contributors
|
||||
* me 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 <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <nuttx/nx/nxglib.h>
|
||||
|
||||
#include "cscaledbitmap.hxx"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Method Implementations
|
||||
****************************************************************************/
|
||||
|
||||
using namespace NXWidgets;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param bitmap The bitmap structure being scaled.
|
||||
* @newSize The new, scaled size of the image
|
||||
*/
|
||||
|
||||
CScaledBitmap::CScaledBitmap(IBitmap *bitmap, struct nxgl_size_s &newSize)
|
||||
: m_bitmap(bitmap), m_size(newSize)
|
||||
{
|
||||
// xScale will be used to convert a request X position to an X position
|
||||
// in the contained bitmap:
|
||||
//
|
||||
// xImage = xRequested * oldWidth / newWidth
|
||||
// = xRequested * xScale
|
||||
|
||||
m_xScale = itob16((uint32_t)m_bitmap->getWidth()) / newSize.w;
|
||||
|
||||
// Similarly, yScale will be used to convert a request Y position to a Y
|
||||
// positionin the contained bitmap:
|
||||
//
|
||||
// yImage = yRequested * oldHeight / newHeight
|
||||
// = yRequested * yScale
|
||||
|
||||
m_xScale = itob16((uint32_t)m_bitmap->getHeight()) / newSize.h;
|
||||
|
||||
// Allocate and initialize the row cache
|
||||
|
||||
size_t stride = bitmap->getStride();
|
||||
m_rowCache[0] = new uint8_t(stride);
|
||||
m_rowCache[1] = new uint8_t(stride);
|
||||
|
||||
// Read the first two rows into the cache
|
||||
|
||||
cacheRows(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
|
||||
CScaledBitmap::~CScaledBitmap(void)
|
||||
{
|
||||
if (m_rowCache[0])
|
||||
{
|
||||
delete m_rowCache[0];
|
||||
}
|
||||
|
||||
if (m_rowCache[1])
|
||||
{
|
||||
delete m_rowCache[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bitmap's color format.
|
||||
*
|
||||
* @return The bitmap's width.
|
||||
*/
|
||||
|
||||
const uint8_t CScaledBitmap::getColorFormat(void) const
|
||||
{
|
||||
return m_bitmap->getColorFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bitmap's color format.
|
||||
*
|
||||
* @return The bitmap's color format.
|
||||
*/
|
||||
|
||||
const uint8_t CScaledBitmap::getBitsPerPixel(void) const
|
||||
{
|
||||
return m_bitmap->getBitsPerPixel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bitmap's width (in pixels/columns).
|
||||
*
|
||||
* @return The bitmap's pixel depth.
|
||||
*/
|
||||
|
||||
const nxgl_coord_t CScaledBitmap::getWidth(void) const
|
||||
{
|
||||
return m_size.w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bitmap's height (in rows).
|
||||
*
|
||||
* @return The bitmap's height (in rows).
|
||||
*/
|
||||
|
||||
const nxgl_coord_t CScaledBitmap::getHeight(void) const
|
||||
{
|
||||
return m_size.h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bitmap's width (in bytes).
|
||||
*
|
||||
* @return The bitmap's width (in bytes).
|
||||
*/
|
||||
|
||||
const size_t CScaledBitmap::getStride(void) const
|
||||
{
|
||||
return (m_bitmap->getBitsPerPixel() * m_size.w + 7) / 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get one row from the bit map image.
|
||||
*
|
||||
* @param x The offset into the row to get
|
||||
* @param y The row number to get
|
||||
* @param width The number of pixels to get from the row
|
||||
* @param data The memory location provided by the caller
|
||||
* in which to return the data. This should be at least
|
||||
* (getWidth()*getBitsPerPixl() + 7)/8 bytes in length
|
||||
* and properly aligned for the pixel color format.
|
||||
* @param True if the run was returned successfully.
|
||||
*/
|
||||
|
||||
bool CScaledBitmap::getRun(nxgl_coord_t x, nxgl_coord_t y,
|
||||
nxgl_coord_t width, FAR void *data)
|
||||
{
|
||||
#if CONFIG_NXWIDGETS_FMT == FB_FMT_RGB8_332 || CONFIG_NXWIDGETS_FMT == FB_FMT_RGB24
|
||||
FAR uint8_t *dest = (FAR uint8_t *)data;
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB16_565
|
||||
FAR uint16_t *dest = (FAR uint16_t *)data;
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB32
|
||||
FAR uint32_t *dest = (FAR uint32_t *)data;
|
||||
#else
|
||||
# error Unsupported, invalid, or undefined color format
|
||||
#endif
|
||||
|
||||
// Check ranges. Casts to unsigned int are ugly but permit one-sided comparisons
|
||||
|
||||
if (((unsigned int)x >= (unsigned int)m_size.w) &&
|
||||
((unsigned int)(x + width) > (unsigned int)m_size.w) &&
|
||||
((unsigned int)y <= (unsigned int)m_size.h))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the row number in the unscaled image corresponding to the
|
||||
// requested y position. This must be either the exact row or the
|
||||
// closest row just before the requested position
|
||||
|
||||
b16_t row16 = y * m_yScale;
|
||||
nxgl_coord_t row = b16toi(row16);
|
||||
|
||||
// Get that row and the one after it into the row cache. We know that
|
||||
// the pixel value that we want is one between the two rows. This
|
||||
// may seem wasteful to read two entire rows. However, in normal usage
|
||||
// we will be traversal each image from top-left to bottom-right in
|
||||
// order. In that case, the caching is most efficient.
|
||||
|
||||
if (!cacheRows(row))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now scale and copy the data from the cached row data
|
||||
|
||||
for (int i = 0; i < width; i++, x++)
|
||||
{
|
||||
// Get the column number in the unscaled row corresponding to the
|
||||
// requested x position. This must be either the exact column or the
|
||||
// closest column just before the requested position
|
||||
|
||||
b16_t column = x * m_xScale;
|
||||
|
||||
// Get the color at the position on the first row
|
||||
|
||||
struct rgbcolor_s color1;
|
||||
if (!rowColor(m_rowCache[0], column, color1))
|
||||
{
|
||||
gdbg("ERROR rowColor failed for the first row\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the color at the position on the first row
|
||||
|
||||
struct rgbcolor_s color2;
|
||||
if (!rowColor(m_rowCache[1], column, color2))
|
||||
{
|
||||
gdbg("ERROR rowColor failed for the second row\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for transparent colors
|
||||
|
||||
bool transparent1;
|
||||
bool transparent2;
|
||||
|
||||
#if CONFIG_NXWIDGETS_FMT == FB_FMT_RGB8_332
|
||||
uint8_t color = RGBTO8(color1.r, color1.g, color1.b);
|
||||
transparent1 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
color = RGBTO8(color2.r, color2.g, color2.b);
|
||||
transparent2 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB16_565
|
||||
uint16_t color = RGBTO16(color1.r, color1.g, color1.b);
|
||||
transparent1 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
color = RGBTO16(color2.r, color2.g, color2.b);
|
||||
transparent2 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB24 || CONFIG_NXWIDGETS_FMT == FB_FMT_RGB32
|
||||
uint32_t color = RGBTO24(color1.r, color1.g, color1.b);
|
||||
transparent1 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
color = RGBTO24(color2.r, color2.g, color2.b);
|
||||
transparent2 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
#else
|
||||
# error Unsupported, invalid, or undefined color format
|
||||
#endif
|
||||
|
||||
// Is one of the colors transparent?
|
||||
|
||||
struct rgbcolor_s scaledColor;
|
||||
b16_t fraction b16frac(row16);
|
||||
|
||||
if (transparent1 || transparent2)
|
||||
{
|
||||
// Yes.. don't interpolate within transparent regions or
|
||||
// between transparent and opaque regions.
|
||||
|
||||
// Get the color closest to the requested position
|
||||
|
||||
if (fraction < b16HALF)
|
||||
{
|
||||
scaledColor.r = color1.r;
|
||||
scaledColor.g = color1.g;
|
||||
scaledColor.b = color1.b;
|
||||
}
|
||||
else
|
||||
{
|
||||
scaledColor.r = color2.r;
|
||||
scaledColor.g = color2.g;
|
||||
scaledColor.b = color2.b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No.. both colors are opaque
|
||||
|
||||
if (!scaleColor(color1, color2, fraction, scaledColor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the interpolated data to the user buffer
|
||||
|
||||
#if CONFIG_NXWIDGETS_FMT == FB_FMT_RGB8_332
|
||||
color = RGBTO8(scaledColor.r, scaledColor.g, scaledColor.b);
|
||||
*dest++ = color;
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB16_565
|
||||
color = RGBTO16(scaledColor.r, scaledColor.g, scaledColor.b);
|
||||
*dest++ = color;
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB24
|
||||
*dest++ = color2.b;
|
||||
*dest++ = color2.r;
|
||||
*dest++ = color2.g;
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB32
|
||||
color = RGBTO24(scaledColor.r, scaledColor.g, scaledColor.b);
|
||||
*dest++ = color;
|
||||
|
||||
#else
|
||||
# error Unsupported, invalid, or undefined color format
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read two rows into the row cache
|
||||
*
|
||||
* @param row - The row number of the first row to cache
|
||||
*/
|
||||
|
||||
bool CScaledBitmap::cacheRows(unsigned int row)
|
||||
{
|
||||
nxgl_coord_t bitmapWidth = m_bitmap->getWidth();
|
||||
nxgl_coord_t bitmapHeight = m_bitmap->getHeight();
|
||||
|
||||
// A common case is to advance by one row. In this case, we only
|
||||
// need to read one row
|
||||
|
||||
if (row == m_row + 1)
|
||||
{
|
||||
// Swap rows
|
||||
|
||||
FAR uint8_t *saveRow = m_rowCache[0];
|
||||
m_rowCache[0] = m_rowCache[1];
|
||||
m_rowCache[1] = saveRow;
|
||||
|
||||
// Save number of the first row that we have in the cache
|
||||
|
||||
m_row = row;
|
||||
|
||||
// Now read the new row into the second row cache buffer
|
||||
|
||||
if (++row >= (unsigned int)bitmapHeight)
|
||||
{
|
||||
row = bitmapHeight - 1;
|
||||
}
|
||||
|
||||
if (!m_bitmap->getRun(0, row, bitmapWidth, &m_rowCache[1]))
|
||||
{
|
||||
gdbg("Failed to read bitmap row %d\n", row);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Do we need to read two new rows? Or do we already have the
|
||||
// request row in the cache?
|
||||
|
||||
else if (row != m_row)
|
||||
{
|
||||
// Read the first row into the cache
|
||||
|
||||
if (row >= (unsigned int)bitmapHeight)
|
||||
{
|
||||
row = bitmapHeight - 1;
|
||||
}
|
||||
|
||||
if (!m_bitmap->getRun(0, row, bitmapWidth, &m_rowCache[0]))
|
||||
{
|
||||
gdbg("Failed to read bitmap row %d\n", row);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save number of the first row that we have in the cache
|
||||
|
||||
m_row = row;
|
||||
|
||||
// Read the next row into the cache
|
||||
|
||||
if (++row >= (unsigned int)bitmapHeight)
|
||||
{
|
||||
row = bitmapHeight - 1;
|
||||
}
|
||||
|
||||
if (!m_bitmap->getRun(0, row, bitmapWidth, &m_rowCache[1]))
|
||||
{
|
||||
gdbg("Failed to read bitmap row %d\n", row);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an two RGB colors and a fractional value, return the scaled
|
||||
* value between the two colors.
|
||||
*
|
||||
* @param incolor1 - The first color to be used
|
||||
* @param incolor2 - The second color to be used
|
||||
* @param fraction - The fractional value
|
||||
* @param outcolor - The returned, scaled color
|
||||
*/
|
||||
|
||||
bool CScaledBitmap::scaleColor(FAR const struct rgbcolor_s &incolor1,
|
||||
FAR const struct rgbcolor_s &incolor2,
|
||||
b16_t fraction, FAR struct rgbcolor_s &outcolor)
|
||||
{
|
||||
unsigned int red;
|
||||
unsigned int green;
|
||||
unsigned int blue;
|
||||
b16_t remainder = b16ONE - fraction;
|
||||
|
||||
red = (unsigned int)incolor1.r * fraction +
|
||||
(unsigned int)incolor2.r * remainder;
|
||||
green = (unsigned int)incolor1.g * fraction +
|
||||
(unsigned int)incolor2.g * remainder;
|
||||
blue = (unsigned int)incolor1.b * fraction +
|
||||
(unsigned int)incolor2.b * remainder;
|
||||
|
||||
outcolor.r = red < 256 ? red : 255;
|
||||
outcolor.g = green < 256 ? green : 255;
|
||||
outcolor.b = blue < 256 ? blue : 255;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an image row and a non-integer column offset, return the
|
||||
* interpolated RGB color value corresponding to that position
|
||||
*
|
||||
* @param row - The pointer to the row in the row cache to use
|
||||
* @param column - The non-integer column offset
|
||||
* @param outcolor - The returned, interpolated color
|
||||
*
|
||||
*/
|
||||
|
||||
bool CScaledBitmap::rowColor(FAR uint8_t *row, b16_t column,
|
||||
FAR struct rgbcolor_s &outcolor)
|
||||
{
|
||||
// This is the col at or just before the pixel of interest
|
||||
|
||||
nxgl_coord_t col1 = b16toi(column);
|
||||
nxgl_coord_t col2 = col1 + 1;
|
||||
|
||||
nxgl_coord_t bitmapWidth = m_bitmap->getWidth();
|
||||
if (col2 >= bitmapWidth)
|
||||
{
|
||||
col2 = bitmapWidth - 1;
|
||||
}
|
||||
|
||||
b16_t fraction = b16frac(column);
|
||||
|
||||
struct rgbcolor_s color1;
|
||||
struct rgbcolor_s color2;
|
||||
|
||||
bool transparent1;
|
||||
bool transparent2;
|
||||
|
||||
#if CONFIG_NXWIDGETS_FMT == FB_FMT_RGB8_332
|
||||
uint8_t color = row[col1];
|
||||
color1.r = RBG8RED(color);
|
||||
color1.g = RBG8GREEN(color);
|
||||
color1.b = RBG8BLUE(color);
|
||||
|
||||
transparent1 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
color = row[col2];
|
||||
color2.r = RBG8RED(color);
|
||||
color2.g = RBG8GREEN(color);
|
||||
color2.b = RBG8BLUE(color);
|
||||
|
||||
transparent2 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB16_565
|
||||
FAR uint16_t *row16 = (FAR uint16_t*)row;
|
||||
uint16_t color = row16[col1];
|
||||
color1.r = RBG16RED(color);
|
||||
color1.g = RBG16GREEN(color);
|
||||
color1.b = RBG16BLUE(color);
|
||||
|
||||
transparent1 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
color = row16[col2];
|
||||
color2.r = RBG16RED(color);
|
||||
color2.g = RBG16GREEN(color);
|
||||
color2.b = RBG16BLUE(color);
|
||||
|
||||
transparent2 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB24
|
||||
unsigned int ndx = 3*col1;
|
||||
color1.r = row[ndx+2];
|
||||
color1.g = row[ndx+1];
|
||||
color1.b = row[ndx];
|
||||
|
||||
uint32_t color = RGBTO24(color1.r, color1.g, color1.b);
|
||||
transparent1 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
ndx = 3*col2;
|
||||
color2.r = row[ndx+2];
|
||||
color2.g = row[ndx+1];
|
||||
color2.b = row[ndx];
|
||||
|
||||
color = RGBTO24(color2.r, color2.g, color2.b);
|
||||
transparent2 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
#elif CONFIG_NXWIDGETS_FMT == FB_FMT_RGB32
|
||||
FAR uint32_t *row32 = (FAR uint32_t*)row;
|
||||
uint32_t color = row32[col1];
|
||||
color1.r = RBG24RED(color);
|
||||
color1.g = RBG24GREEN(color);
|
||||
color1.b = RBG24BLUE(color);
|
||||
|
||||
transparent1 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
color = row32[col2];
|
||||
color2.r = RBG24RED(color);
|
||||
color2.g = RBG24GREEN(color);
|
||||
color2.b = RBG24BLUE(color);
|
||||
|
||||
transparent2 = (color == CONFIG_NXWIDGETS_TRANSPARENT_COLOR);
|
||||
|
||||
#else
|
||||
# error Unsupported, invalid, or undefined color format
|
||||
#endif
|
||||
|
||||
// Is one of the colors transparent?
|
||||
|
||||
if (transparent1 || transparent2)
|
||||
{
|
||||
// Yes.. don't interpolate within transparent regions or
|
||||
// between transparent and opaque regions.
|
||||
|
||||
// Return the color closest to the requested position
|
||||
|
||||
if (fraction < b16HALF)
|
||||
{
|
||||
outcolor.r = color1.r;
|
||||
outcolor.g = color1.b;
|
||||
outcolor.g = color1.g;
|
||||
}
|
||||
else
|
||||
{
|
||||
outcolor.r = color2.r;
|
||||
outcolor.g = color2.b;
|
||||
outcolor.g = color2.g;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No.. both colors are opaque
|
||||
|
||||
return scaleColor(color1, color2, fraction, outcolor);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* include/nuttx/rgbcolors.h
|
||||
* User-friendly RGB color definitions
|
||||
*
|
||||
* Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2010-2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -45,7 +45,7 @@
|
|||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
/* Color Creation and Conversion Macros *************************************/
|
||||
/* This macro creates RGB24 from 8:8:8 RGB */
|
||||
/* This macro creates RGB24 from 8:8:8 RGB */
|
||||
|
||||
#define RGBTO24(r,g,b) \
|
||||
((uint32_t)((r) & 0xff) << 16 | (uint32_t)((g) & 0xff) << 8 | (uint32_t)((b) & 0xff))
|
||||
|
@ -268,11 +268,34 @@
|
|||
#define RGB8_YELLOW 0xfc
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This is a generic representation of an RGB color */
|
||||
|
||||
struct rgbcolor_s
|
||||
{
|
||||
uint8_t r; /* Red value */
|
||||
uint8_t b; /* Blue value */
|
||||
uint8_t g; /* Green value */
|
||||
};
|
||||
|
||||
/* This is a generic representation of an RGB color with ALPHA */
|
||||
|
||||
struct argbcolor_s
|
||||
{
|
||||
uint8_t a; /* Alpha value (transparency) */
|
||||
uint8_t r; /* Red value */
|
||||
uint8_t b; /* Blue value */
|
||||
uint8_t g; /* Green value */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
|
|
Loading…
Reference in New Issue