pixel.hh revision 12366
112366Sgabeblack@google.com/* 212366Sgabeblack@google.com * Copyright (c) 2015 ARM Limited 312366Sgabeblack@google.com * All rights reserved 412366Sgabeblack@google.com * 512366Sgabeblack@google.com * The license below extends only to copyright in the software and shall 612366Sgabeblack@google.com * not be construed as granting a license to any other intellectual 712366Sgabeblack@google.com * property including but not limited to intellectual property relating 812366Sgabeblack@google.com * to a hardware implementation of the functionality of the software 912366Sgabeblack@google.com * licensed hereunder. You may use the software subject to the license 1012366Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated 1112366Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software, 1212366Sgabeblack@google.com * modified or unmodified, in source code or in binary form. 1312366Sgabeblack@google.com * 1412366Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 1512366Sgabeblack@google.com * modification, are permitted provided that the following conditions are 1612366Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 1712366Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 1812366Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1912366Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2012366Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 2112366Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 2212366Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 2312366Sgabeblack@google.com * this software without specific prior written permission. 2412366Sgabeblack@google.com * 2512366Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612366Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712366Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812366Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912366Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012366Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112366Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212366Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312366Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412366Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512366Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612366Sgabeblack@google.com * 3712366Sgabeblack@google.com * Authors: Andreas Sandberg 3812366Sgabeblack@google.com */ 3912366Sgabeblack@google.com 4012366Sgabeblack@google.com#ifndef __BASE_PIXEL_HH__ 4112366Sgabeblack@google.com#define __BASE_PIXEL_HH__ 4212366Sgabeblack@google.com 4312366Sgabeblack@google.com#include <cmath> 4412366Sgabeblack@google.com#include <cstdint> 4512366Sgabeblack@google.com#include <string> 4612366Sgabeblack@google.com#include <vector> 4712366Sgabeblack@google.com 4812366Sgabeblack@google.com#include "base/compiler.hh" 4912366Sgabeblack@google.com#include "base/cprintf.hh" 5012366Sgabeblack@google.com#include "base/str.hh" 5112366Sgabeblack@google.com#include "base/types.hh" 5212366Sgabeblack@google.com 5312366Sgabeblack@google.com/** 5412366Sgabeblack@google.com * Internal gem5 representation of a Pixel. 5512366Sgabeblack@google.com */ 5612366Sgabeblack@google.comstruct Pixel 5712366Sgabeblack@google.com{ 5812366Sgabeblack@google.com Pixel() 5912366Sgabeblack@google.com : red(0), green(0), blue(0), padding(0) {} 6012366Sgabeblack@google.com 6112366Sgabeblack@google.com Pixel(uint8_t _red, uint8_t _green, uint8_t _blue) 6212366Sgabeblack@google.com : red(_red), green(_green), blue(_blue), padding(0) {} 6312366Sgabeblack@google.com 6412366Sgabeblack@google.com uint8_t red; 6512366Sgabeblack@google.com uint8_t green; 6612366Sgabeblack@google.com uint8_t blue; 6712366Sgabeblack@google.com uint8_t padding; 6812366Sgabeblack@google.com}; 6912366Sgabeblack@google.com 7012366Sgabeblack@google.cominline bool 7112366Sgabeblack@google.comoperator==(const Pixel &lhs, const Pixel &rhs) 7212366Sgabeblack@google.com{ 7312366Sgabeblack@google.com return lhs.red == rhs.red && 7412366Sgabeblack@google.com lhs.green == rhs.green && 7512366Sgabeblack@google.com lhs.blue == rhs.blue && 7612366Sgabeblack@google.com lhs.padding == rhs.padding; 7712366Sgabeblack@google.com} 7812366Sgabeblack@google.com 7912366Sgabeblack@google.com/** 8012366Sgabeblack@google.com * Configurable RGB pixel converter. 8112366Sgabeblack@google.com * 8212366Sgabeblack@google.com * This class converts between external RGB representations and gem5's 8312366Sgabeblack@google.com * internal Pixel representation. The class assumes that pixels are 8412366Sgabeblack@google.com * stored in a word of configurable length (up to 32 bits). Individual 8512366Sgabeblack@google.com * pixels are assumed to be represented by contiguous bit ranges in 8612366Sgabeblack@google.com * the word (i.e., it is possible to shift and mask out a contiguous 8712366Sgabeblack@google.com * bit range for each pixel). 8812366Sgabeblack@google.com */ 8912366Sgabeblack@google.comclass PixelConverter 9012366Sgabeblack@google.com{ 9112366Sgabeblack@google.com public: 9212366Sgabeblack@google.com /** 9312366Sgabeblack@google.com * Color channel conversion and scaling helper class. 9412366Sgabeblack@google.com */ 9512366Sgabeblack@google.com struct Channel { 9612366Sgabeblack@google.com /** 9712366Sgabeblack@google.com * @param offset Offset in bits. 9812366Sgabeblack@google.com * @param width Width in bits. 9912366Sgabeblack@google.com */ 10012366Sgabeblack@google.com Channel(unsigned offset, unsigned width); 10112366Sgabeblack@google.com 10212366Sgabeblack@google.com /** 10312366Sgabeblack@google.com * Get the value of a single color channel represented as an 10412366Sgabeblack@google.com * 8-bit number. 10512366Sgabeblack@google.com */ 10612366Sgabeblack@google.com uint8_t toPixel(uint32_t word) const { 10712366Sgabeblack@google.com return round(((word >> offset) & mask) * factor); 10812366Sgabeblack@google.com } 10912366Sgabeblack@google.com 11012366Sgabeblack@google.com /** 11112366Sgabeblack@google.com * Convert an 8-bit representation of a color into an external 11212366Sgabeblack@google.com * format. 11312366Sgabeblack@google.com */ 11412366Sgabeblack@google.com uint32_t fromPixel(uint8_t ch) const { 11512366Sgabeblack@google.com return (static_cast<uint8_t>(round(ch / factor)) & mask) << offset; 11612366Sgabeblack@google.com } 11712366Sgabeblack@google.com 11812366Sgabeblack@google.com /** Offset in bits */ 11912366Sgabeblack@google.com unsigned offset; 12012366Sgabeblack@google.com /** Bit mask (after shifting) */ 12112366Sgabeblack@google.com unsigned mask; 12212366Sgabeblack@google.com /** 12312366Sgabeblack@google.com * Scaling factor when converting to the full range of an 12412366Sgabeblack@google.com * 8-bit color channel 12512366Sgabeblack@google.com */ 12612366Sgabeblack@google.com float factor; 12712366Sgabeblack@google.com }; 12812366Sgabeblack@google.com 12912366Sgabeblack@google.com PixelConverter(unsigned length, 13012366Sgabeblack@google.com unsigned ro, unsigned go, unsigned bo, 13112366Sgabeblack@google.com unsigned rw, unsigned gw, unsigned bw, 13212366Sgabeblack@google.com ByteOrder byte_order = LittleEndianByteOrder); 13312366Sgabeblack@google.com 13412366Sgabeblack@google.com /** Get the Pixel representation of a color word. */ 13512366Sgabeblack@google.com Pixel toPixel(uint32_t word) const { 13612366Sgabeblack@google.com return Pixel(ch_r.toPixel(word), 13712366Sgabeblack@google.com ch_g.toPixel(word), 13812366Sgabeblack@google.com ch_b.toPixel(word)); 13912366Sgabeblack@google.com } 14012366Sgabeblack@google.com 14112366Sgabeblack@google.com /** Get a Pixel representation by reading a word from memory. */ 14212366Sgabeblack@google.com Pixel toPixel(const uint8_t *rfb) const { 14312366Sgabeblack@google.com return toPixel(readWord(rfb)); 14412366Sgabeblack@google.com } 14512366Sgabeblack@google.com 14612366Sgabeblack@google.com /** Convert a Pixel into a color word */ 14712366Sgabeblack@google.com uint32_t fromPixel(const Pixel &pixel) const { 14812366Sgabeblack@google.com return ch_r.fromPixel(pixel.red) | 14912366Sgabeblack@google.com ch_g.fromPixel(pixel.green) | 15012366Sgabeblack@google.com ch_b.fromPixel(pixel.blue); 15112366Sgabeblack@google.com } 15212366Sgabeblack@google.com 15312366Sgabeblack@google.com /** 15412366Sgabeblack@google.com * Convert a pixel into a color word and store the resulting word 15512366Sgabeblack@google.com * in memory. 15612366Sgabeblack@google.com */ 15712366Sgabeblack@google.com void fromPixel(uint8_t *rfb, const Pixel &pixel) const { 15812366Sgabeblack@google.com writeWord(rfb, fromPixel(pixel)); 15912366Sgabeblack@google.com } 16012366Sgabeblack@google.com 16112366Sgabeblack@google.com /** 16212366Sgabeblack@google.com * Read a word of a given length and endianness from memory. 16312366Sgabeblack@google.com * 16412366Sgabeblack@google.com * The number of bytes read from memory is determined by the 16512366Sgabeblack@google.com * length of a color word. Note that some of the bytes may be 16612366Sgabeblack@google.com * padding. 16712366Sgabeblack@google.com * 16812366Sgabeblack@google.com * @param p Pointer to the first byte in the word. 16912366Sgabeblack@google.com * @return Word in host endianness. 17012366Sgabeblack@google.com */ 17112366Sgabeblack@google.com uint32_t readWord(const uint8_t *p) const; 17212366Sgabeblack@google.com /** 17312366Sgabeblack@google.com * Write a word of a given length and endianness to memory. 17412366Sgabeblack@google.com * 17512366Sgabeblack@google.com * @param p Pointer to the first byte in memory. 17612366Sgabeblack@google.com * @param word Word to store (host endianness). 17712366Sgabeblack@google.com */ 17812366Sgabeblack@google.com void writeWord(uint8_t *p, uint32_t word) const; 17912366Sgabeblack@google.com 18012366Sgabeblack@google.com /** Bytes per pixel when stored in memory (including padding) */ 18112366Sgabeblack@google.com unsigned length; 18212366Sgabeblack@google.com /** 18312366Sgabeblack@google.com * Number of bits used to represent one pixel value (excluding 18412366Sgabeblack@google.com * padding). This could be less than length * 8 if the pixel value 18512366Sgabeblack@google.com * is padded. 18612366Sgabeblack@google.com */ 18712366Sgabeblack@google.com unsigned depth; 18812366Sgabeblack@google.com /** Byte order when stored to memory. */ 18912366Sgabeblack@google.com ByteOrder byte_order; 19012366Sgabeblack@google.com 19112366Sgabeblack@google.com /** Red channel conversion helper */ 19212366Sgabeblack@google.com Channel ch_r; 19312366Sgabeblack@google.com /** Green channel conversion helper */ 19412366Sgabeblack@google.com Channel ch_g; 19512366Sgabeblack@google.com /** Blue channel conversion helper */ 19612366Sgabeblack@google.com Channel ch_b; 19712366Sgabeblack@google.com 19812366Sgabeblack@google.com /** Predefined 32-bit RGB (red in least significant bits, 8 19912366Sgabeblack@google.com * bits/channel, little endian) conversion helper */ 20012366Sgabeblack@google.com static const PixelConverter rgba8888_le; 20112366Sgabeblack@google.com /** Predefined 16-bit RGB565 (red in least significant bits, 20212366Sgabeblack@google.com * little endian) conversion helper */ 20312366Sgabeblack@google.com static const PixelConverter rgb565_le; 20412366Sgabeblack@google.com 20512366Sgabeblack@google.com /** Predefined 32-bit RGB (red in least significant bits, 8 20612366Sgabeblack@google.com * bits/channel, big endian) conversion helper */ 20712366Sgabeblack@google.com static const PixelConverter rgba8888_be; 20812366Sgabeblack@google.com /** Predefined 16-bit RGB565 (red in least significant bits, 20912366Sgabeblack@google.com * big endian) conversion helper */ 21012366Sgabeblack@google.com static const PixelConverter rgb565_be; 21112366Sgabeblack@google.com}; 21212366Sgabeblack@google.com 21312366Sgabeblack@google.cominline bool 21412366Sgabeblack@google.comto_number(const std::string &value, Pixel &retval) 21512366Sgabeblack@google.com{ 21612366Sgabeblack@google.com uint32_t num; 21712366Sgabeblack@google.com if (!to_number(value, num)) 21812366Sgabeblack@google.com return false; 21912366Sgabeblack@google.com 22012366Sgabeblack@google.com retval = PixelConverter::rgba8888_le.toPixel(num); 22112366Sgabeblack@google.com return true; 22212366Sgabeblack@google.com} 22312366Sgabeblack@google.com 22412366Sgabeblack@google.cominline std::ostream & 22512366Sgabeblack@google.comoperator<<(std::ostream &os, const Pixel &pxl) 22612366Sgabeblack@google.com{ 22712366Sgabeblack@google.com os << csprintf("%#.08x", PixelConverter::rgba8888_le.fromPixel(pxl)); 22812366Sgabeblack@google.com return os; 22912366Sgabeblack@google.com} 23012366Sgabeblack@google.com 23112366Sgabeblack@google.com#endif // __BASE_PIXEL_HH__ 232