diff options
-rw-r--r-- | graphics/dither.cpp | 313 | ||||
-rw-r--r-- | graphics/dither.h | 195 | ||||
-rw-r--r-- | graphics/module.mk | 1 |
3 files changed, 0 insertions, 509 deletions
diff --git a/graphics/dither.cpp b/graphics/dither.cpp deleted file mode 100644 index 3876db152b..0000000000 --- a/graphics/dither.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "graphics/dither.h" - -#include "common/endian.h" -#include "common/stream.h" - -namespace Graphics { - -PaletteLUT::PaletteLUT(byte depth, PaletteFormat format) { - assert((depth > 1) && (depth < 9)); - - // For adjusting depth - _depth1 = depth; - _depth2 = 2 * _depth1; - _shift = 8 - _depth1; - - // The table's dimensions - _dim1 = (1 << _depth1); - _dim2 = _dim1 * _dim1; - _dim3 = _dim1 * _dim1 * _dim1; - - _format = format; - - // What's already built - _got = _dim1; - _gots = new byte[_dim1]; - - // The lookup table - _lut = new byte[_dim3]; - - memset(_lutPal, 0, 768); - memset(_realPal, 0, 768); - memset(_gots, 1, _dim1); -} - -void PaletteLUT::setPalette(const byte *palette, PaletteFormat format, - byte depth, int transp) { - - assert((depth > 1) && (depth < 9)); - - _transp = transp; - - int shift = 8 - depth; - - // Checking for the table's and the palette's pixel format - if ((_format == kPaletteRGB) && (format == kPaletteYUV)) { - byte *newPal = _realPal; - const byte *oldPal = palette; - for (int i = 0; i < 256; i++, newPal += 3, oldPal += 3) - YUV2RGB(oldPal[0] << shift, oldPal[1] << shift, oldPal[2] << shift, - newPal[0], newPal[1], newPal[2]); - } else if ((_format == kPaletteYUV) && (format == kPaletteRGB)) { - byte *newPal = _realPal; - const byte *oldPal = palette; - for (int i = 0; i < 256; i++, newPal += 3, oldPal += 3) - RGB2YUV(oldPal[0] << shift, oldPal[1] << shift, oldPal[2] << shift, - newPal[0], newPal[1], newPal[2]); - } else - memcpy(_realPal, palette, 768); - - // Using the specified depth for the lookup - byte *newPal = _lutPal, *oldPal = _realPal; - for (int i = 0; i < 768; i++) - *newPal++ = (*oldPal++) >> _shift; - - // Everything has to be rebuilt - _got = 0; - memset(_gots, 0, _dim1); -} - -PaletteLUT::~PaletteLUT() { - delete[] _lut; - delete[] _gots; -} - -void PaletteLUT::buildNext() { - if (_got >= _dim1) - return; - - build(_got++); -} - -#define SQR(x) ((x) * (x)) -// Building one "slice" -void PaletteLUT::build(int d1) { - // First dimension - byte *lut = _lut + d1 * _dim2; - - // Second dimension - for (uint32 j = 0; j < _dim1; j++) { - // Third dimension - for (uint32 k = 0; k < _dim1; k++) { - const byte *p = _lutPal; - uint32 d = 0xFFFFFFFF; - byte n = 0; - - // Going over every palette entry, searching for the closest - for (int c = 0; c < 256; c++, p += 3) { - // Ignore the transparent color - if (c == _transp) - continue; - - uint32 di = SQR(d1 - p[0]) + SQR(j - p[1]) + SQR(k - p[2]); - if (di < d) { - d = di; - n = c; - if (d == 0) - break; - } - } - - *lut++ = n; - } - } - - // Got this slice now - _gots[d1] = 1; -} - -inline int PaletteLUT::getIndex(byte c1, byte c2, byte c3) const { - return ((c1 >> _shift) << _depth2) | ((c2 >> _shift) << _depth1) | (c3 >> _shift); -} - -void PaletteLUT::getEntry(byte index, byte &c1, byte &c2, byte &c3) const { - c1 = _realPal[index * 3 + 0]; - c2 = _realPal[index * 3 + 1]; - c3 = _realPal[index * 3 + 2]; -} - -byte PaletteLUT::findNearest(byte c1, byte c2, byte c3) { - return _lut[getIndex(c1, c2, c3)]; -} - -byte PaletteLUT::findNearest(byte c1, byte c2, byte c3, byte &nC1, byte &nC2, byte &nC3) { - // If we don't have the required "slice" yet, build it - if (!_gots[c1 >> _shift]) - build(c1 >> _shift); - - int palIndex = _lut[getIndex(c1, c2, c3)]; - int i = palIndex * 3; - - nC1 = _realPal[i + 0]; - nC2 = _realPal[i + 1]; - nC3 = _realPal[i + 2]; - - return palIndex; -} - -bool PaletteLUT::save(Common::WriteStream &stream) { - // The table has to be completely built before we can save - while (_got < _dim1) - buildNext(); - - stream.writeUint32BE(MKTAG('P','L','U','T')); // Magic - stream.writeUint32BE(kVersion); - stream.writeByte(_depth1); - if (stream.write(_realPal, 768) != 768) - return false; - if (stream.write(_lutPal, 768) != 768) - return false; - if (stream.write(_lut, _dim3) != _dim3) - return false; - if (!stream.flush()) - return false; - - if (stream.err()) - return false; - - return true; -} - -bool PaletteLUT::load(Common::SeekableReadStream &stream) { - // _realPal + _lutPal + _lut + _depth1 + magic + version - int32 needSize = 768 + 768 + _dim3 + 1 + 4 + 4; - - if ((stream.size() - stream.pos()) < needSize) - return false; - - // Magic - if (stream.readUint32BE() != MKTAG('P','L','U','T')) - return false; - - if (stream.readUint32BE() != kVersion) - return false; - - byte depth1 = stream.readByte(); - - if (depth1 != _depth1) - return false; - - if (stream.read(_realPal, 768) != 768) - return false; - if (stream.read(_lutPal, 768) != 768) - return false; - if (stream.read(_lut, _dim3) != _dim3) - return false; - - _got = _dim1; - memset(_gots, 1, _dim1); - - return true; -} - -SierraLight::SierraLight(int16 width, PaletteLUT *palLUT) { - assert(width > 0); - - _width = width; - _palLUT = palLUT; - - // Big buffer for the errors of the current and next line - _errorBuf = new int32[3 * (2 * (_width + 2*1))]; - memset(_errorBuf, 0, (3 * (2 * (_width + 2*1))) * sizeof(int32)); - - _curLine = 0; - _errors[0] = _errorBuf + 3; - _errors[1] = _errors[0] + 3 * (_width + 2*1); -} - -SierraLight::~SierraLight() { - delete[] _errorBuf; -} - -void SierraLight::newFrame() { - _curLine = 0; - memset(_errors[0], 0, 3 * _width * sizeof(int32)); - memset(_errors[1], 0, 3 * _width * sizeof(int32)); -} - -void SierraLight::nextLine() { - // Clear the finished line, it will become the last line in the buffer - memset(_errors[_curLine], 0, 3 * _width * sizeof(int32)); - - _curLine = (_curLine + 1) % 2; -} - -byte SierraLight::dither(byte c1, byte c2, byte c3, uint32 x) { - assert(_palLUT); - assert(x < (uint32)_width); - - int32 eC1, eC2, eC3; - - getErrors(x, eC1, eC2, eC3); - - // Apply error on values - c1 = CLIP<int>(c1 + eC1, 0, 255); - c2 = CLIP<int>(c2 + eC2, 0, 255); - c3 = CLIP<int>(c3 + eC3, 0, 255); - - // Find color - byte newC1, newC2, newC3; - byte newPixel = _palLUT->findNearest(c1, c2, c3, newC1, newC2, newC3); - - // Calculate new error - eC1 = c1 - newC1; - eC2 = c2 - newC2; - eC3 = c3 - newC3; - - // Add them - addErrors(x, eC1, eC2, eC3); - - return newPixel; -} - -inline void SierraLight::getErrors(uint32 x, int32 &eC1, int32 &eC2, int32 &eC3) { - int32 *errCur = _errors[_curLine]; - - x *= 3; - eC1 = errCur[x + 0] >> 2; - eC2 = errCur[x + 1] >> 2; - eC3 = errCur[x + 2] >> 2; -} - -inline void SierraLight::addErrors(uint32 x, int32 eC1, int32 eC2, int32 eC3) { - int32 *errCur = _errors[_curLine]; - int32 *errNext = _errors[(_curLine + 1) % 2]; - - // Indices for current error - int x0 = 3 * (x + 1); - int x1 = 3 * (x + 0); - int x2 = 3 * (x - 1); - - errCur [x0 + 0] += eC1 << 1; - errCur [x0 + 1] += eC2 << 1; - errCur [x0 + 2] += eC3 << 1; - errNext[x1 + 0] += eC1; - errNext[x1 + 1] += eC2; - errNext[x1 + 2] += eC3; - errNext[x2 + 0] += eC1; - errNext[x2 + 1] += eC2; - errNext[x2 + 2] += eC3; -} - -} // End of namespace Graphics diff --git a/graphics/dither.h b/graphics/dither.h deleted file mode 100644 index dbde03df82..0000000000 --- a/graphics/dither.h +++ /dev/null @@ -1,195 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef GRAPHICS_DITHER_H -#define GRAPHICS_DITHER_H - -#include "common/util.h" - -namespace Common { -class SeekableReadStream; -class WriteStream; -} - -namespace Graphics { - -/** A palette lookup table to find the nearest matching entry of a fixed palette to a true color. - * - * The table can be build up in slices, one slice consisting of all entries for - * one value of the first color component. - */ -class PaletteLUT { -public: - /** Palette format. */ - enum PaletteFormat { - kPaletteRGB, ///< Palette in RGB colorspace - kPaletteYUV ///< Palette in YUV colorspace - }; - - /** Converting a color from YUV to RGB colorspace. */ - inline static void YUV2RGB(byte y, byte u, byte v, byte &r, byte &g, byte &b) { - r = CLIP<int>(y + ((1357 * (v - 128)) >> 10), 0, 255); - g = CLIP<int>(y - (( 691 * (v - 128)) >> 10) - ((333 * (u - 128)) >> 10), 0, 255); - b = CLIP<int>(y + ((1715 * (u - 128)) >> 10), 0, 255); - } - /** Converting a color from RGB to YUV colorspace. */ - inline static void RGB2YUV(byte r, byte g, byte b, byte &y, byte &u, byte &v) { - y = CLIP<int>( ((r * 306) >> 10) + ((g * 601) >> 10) + ((b * 117) >> 10) , 0, 255); - u = CLIP<int>(-((r * 172) >> 10) - ((g * 340) >> 10) + ((b * 512) >> 10) + 128, 0, 255); - v = CLIP<int>( ((r * 512) >> 10) - ((g * 429) >> 10) - ((b * 83) >> 10) + 128, 0, 255); - } - - /** Create a lookup table of a given depth and palette format. - * - * @param depth How many bits of each color component to consider. - * @param format The format the palette should be in. - */ - PaletteLUT(byte depth, PaletteFormat format); - ~PaletteLUT(); - - /** Setting a palette. - * - * Any already built slices will be purged. - * - * @param palette The palette, plain 256 * 3 color components. - * @param format The format the palette is in. - * @param depth The number of significant bits in each color component. - * @param transp An index that's seen as transparent and therefore ignored. - */ - void setPalette(const byte *palette, PaletteFormat format, byte depth, int transp = -1); - - /** Build the next slice. - * - * This will build the next slice, if any. - */ - void buildNext(); - - /** Querying the color components to a given palette entry index. */ - void getEntry(byte index, byte &c1, byte &c2, byte &c3) const; - /** Finding the nearest matching entry. - * - * @param c1 The first component of the wanted color. - * @param c2 The second component of the wanted color. - * @param c3 The third component of the wanted color. - * @return The palette entry matching the wanted color best. - */ - byte findNearest(byte c1, byte c2, byte c3); - /** Finding the nearest matching entry, together with its color components. - * - * @param c1 The first component of the wanted color. - * @param c2 The second component of the wanted color. - * @param c3 The third component of the wanted color. - * @paran nC1 The first component of the found color. - * @paran nC2 The second component of the found color. - * @paran nC3 The third component of the found color. - * @return The palette entry matching the wanted color best. - */ - byte findNearest(byte c1, byte c2, byte c3, byte &nC1, byte &nC2, byte &nC3); - - /** Save the table to a stream. - * - * This will build the whole table first. - */ - bool save(Common::WriteStream &stream); - /** Load the table from a stream. */ - bool load(Common::SeekableReadStream &stream); - -private: - static const uint32 kVersion = 1; - - byte _depth1; ///< The table's depth for one dimension. - byte _depth2; ///< The table's depth for two dimensions. - byte _shift; ///< Amount to shift to adjust for the table's depth. - - uint32 _dim1; ///< The table's entry offset for one dimension. - uint32 _dim2; ///< The table's entry offset for two dimensions. - uint32 _dim3; ///< The table's entry offset for three dimensions. - - int _transp; ///< The transparent palette index. - - PaletteFormat _format; ///< The table's palette format. - byte _lutPal[768]; ///< The palette used for looking up a color. - byte _realPal[768]; ///< The original palette. - - uint32 _got; ///< Number of slices generated. - byte *_gots; ///< Map of generated slices. - byte *_lut; ///< The lookup table. - - /** Building a specified slice. */ - void build(int d1); - /** Calculates the index into the lookup table for a given color. */ - inline int getIndex(byte c1, byte c2, byte c3) const; -}; - -/** The Sierra-2-4A ("Filter Light") error distribution dithering algorithm. - * - * The image will be dithered line by line and pixel by pixel, without earlier - * values having to be changed. -*/ -class SierraLight { -public: - /** Constructor. - * - * @param width The width of the image to dither. - * @param palLUT The palette to which to dither. - */ - SierraLight(int16 width, PaletteLUT *palLUT); - ~SierraLight(); - - /** Signals that a new frame or image is about to be dithered. - * - * This clears all collected errors, so that a new image (of the same - * height and with the same palette) can be dithered. - */ - void newFrame(); - /** Signals that a new line is about the begin. - * - * The current line's errors will be forgotten and values collected for the - * next line will now count as the current line's. - */ - void nextLine(); - /** Dither a pixel. - * - * @param c1 The first color component of the pixel. - * @param c2 The second color component of the pixel. - * @param c3 The third color component of the pixel. - * @param x The pixel's x coordinate within the image. - */ - byte dither(byte c1, byte c2, byte c3, uint32 x); - -protected: - int16 _width; ///< The image's width. - - PaletteLUT *_palLUT; ///< The palette against which to dither. - - int32 *_errorBuf; ///< Big buffer for all collected errors. - int32 *_errors[2]; ///< Pointers into the error buffer for two lines. - int _curLine; ///< Which one is the current line? - - /** Querying a pixel's errors. */ - inline void getErrors(uint32 x, int32 &eC1, int32 &eC2, int32 &eC3); - /** Adding a pixel's errors. */ - inline void addErrors(uint32 x, int32 eC1, int32 eC2, int32 eC3); -}; - -} // End of namespace Graphics - -#endif diff --git a/graphics/module.mk b/graphics/module.mk index 469ee42047..02c88d98ba 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -3,7 +3,6 @@ MODULE := graphics MODULE_OBJS := \ conversion.o \ cursorman.o \ - dither.o \ font.o \ fontman.o \ fonts/bdf.o \ |